@astronomy-bundle/solar-eclipse
v9.38.0
Published
Solar eclipse calculations for the astronomy bundle
Maintainers
Readme
Part of the Astronomy Bundle.
Solar Eclipse
The solarEclipse package provides solar eclipse calculations for any location on Earth. It uses Besselian Elements — pre-computed polynomial coefficients describing the Moon's shadow geometry — to determine eclipse type, contact times, magnitude, and obscuration at a specific geographic location and point in time.
Contents
- Install
- API Reference
- Eclipse Catalogue
- SolarEclipse
- LocalSolarEclipse (Eclipse + Location)
- LocalEclipseCircumstances (Eclipse + Location + Time)
Install
With npm: npm install @astronomy-bundle/solar-eclipse @astronomy-bundle/core
With yarn: yarn add @astronomy-bundle/solar-eclipse @astronomy-bundle/core
With pnpm: pnpm add @astronomy-bundle/solar-eclipse @astronomy-bundle/core
API Reference
Eclipse Catalogue
Two pre-computed eclipse catalogues are provided as separate subpath exports. Use them to list available eclipse dates, look up Besselian elements by date, and pass the result to SolarEclipse.createFromBesselianElements.
Both catalogue entrypoints export a Catalogue class with the same methods:
Catalogue.getAvailableEclipseDates(dateFrom?, dateTo?): returns sorted eclipse dates inYYYY-MM-DDformat. The optional boundaries are inclusive.Catalogue.getBesselianElements(date): returns the parsed Besselian elements for an eclipse date. It throws when the date is outside the catalogue range or when no eclipse exists on that date.
Standard catalogue (1900–2100)
Import from @astronomy-bundle/solar-eclipse/catalogue for the standard catalogue. It contains 454 eclipses, from 1900-05-28 to 2100-09-04, and is the default choice for modern dates. Requests outside the 1900–2100 catalogue range throw with a hint to use the full catalogue instead.
import {SolarEclipse} from '@astronomy-bundle/solar-eclipse';
import {Catalogue} from '@astronomy-bundle/solar-eclipse/catalogue';
const availableDates = Catalogue.getAvailableEclipseDates('2026-01-01', '2026-12-31');
const elements = Catalogue.getBesselianElements('2026-08-12');
const eclipse = SolarEclipse.createFromBesselianElements(elements);Full catalogue (−1999–3000)
⚠️ Warning: The full catalogue is about 1 MB uncompressed. Avoid importing it in browser bundles or size-sensitive environments unless necessary.
For eclipses outside the standard range, import from @astronomy-bundle/solar-eclipse/catalogue-full. It contains 11,898 eclipses, from -1999-06-12 to 3000-10-19, while leaving the standard catalogue entrypoint unchanged. Negative years use signed astronomical year numbering.
import {SolarEclipse} from '@astronomy-bundle/solar-eclipse';
import {Catalogue} from '@astronomy-bundle/solar-eclipse/catalogue-full';
const availableDates = Catalogue.getAvailableEclipseDates(); // All dates from -1999-06-12 to 3000-10-19
const elements = Catalogue.getBesselianElements('-0500-03-14');
const eclipse = SolarEclipse.createFromBesselianElements(elements);SolarEclipse
SolarEclipse represents a solar eclipse event and provides global eclipse properties such as type, greatest eclipse location and time, and peak magnitude. It is the primary entry point for eclipse calculations.
Example: Total solar eclipse on 2 July 2019
import {SolarEclipse} from '@astronomy-bundle/solar-eclipse';
import {Catalogue} from '@astronomy-bundle/solar-eclipse/catalogue';
const elements = Catalogue.getBesselianElements('2019-07-02');
const eclipse = SolarEclipse.createFromBesselianElements(elements);Create a SolarEclipse object
Description: The createFromBesselianElements static method creates a SolarEclipse instance from a BesselianElements object. This is the only static constructor on SolarEclipse. Use the built-in Catalogue entrypoints for date-based lookup, or pass custom pre-computed Besselian elements.
import {SolarEclipse, parseBesselianElements} from '@astronomy-bundle/solar-eclipse';
// ASE 2016-09-01
const elements = parseBesselianElements([
2457632.88058, 9.0, -3.0, 3.0, 0, 0,
-0.16139600, 0.50406349, -0.00002140, -0.00000631,
-0.29965001, -0.14815210, -0.00002580, 0.00000178,
8.06330013, -0.01480200, -0.00000200,
315.03155518, 15.00454044, 0.00000000,
0.55792803, 0.00011150, -0.00001050,
0.01173100, 0.00011100, -0.00001040,
0.00463390, 0.00461090, 135
]);
const eclipse = SolarEclipse.createFromBesselianElements(elements);Eclipse type
Description: Returns the global eclipse type as a SolarEclipseType value. Possible values are 'partial', 'total', 'annular', and 'hybrid'.
const type = eclipse.getType();The result of the calculation should be: total
Saros series
Description: Returns the Saros series number the eclipse belongs to. Eclipses of the same Saros series recur roughly every 18 years, 11 days, and 8 hours.
const saros = eclipse.getSaros();The result of the calculation should be: 127
Location of greatest eclipse
Description: Returns the geographic coordinates {lat, lon} (in decimal degrees) of the point on Earth's surface where the eclipse is greatest — i.e., where the Moon's shadow axis passes closest to the centre of the Earth.
const {lat, lon} = eclipse.getLocationOfGreatestEclipse();The result of the calculation should be:
lat: -17.388965
lon: -108.998853
Time of greatest eclipse
Description: Returns a TimeOfInterest representing the moment of greatest eclipse in Terrestrial Time (TT).
const toi = eclipse.getTimeOfGreatestEclipse();
const {year, month, day, hour, min, sec} = toi.getTime();The result of the calculation should be: 2019-07-02 19:22:58
Gamma
Description: Returns gamma — the least distance of the Moon's shadow axis from the centre of the Earth at greatest eclipse, measured in units of Earth's equatorial radius. It is positive when the axis passes north of the centre and negative when it passes south. A value near 0 indicates a central eclipse crossing near the equator, while a magnitude above roughly 1 indicates a partial eclipse whose axis misses the Earth.
const gamma = eclipse.getGamma();The result of the calculation should be: -0.646562
Maximum magnitude
Description: Returns the eclipse magnitude at greatest eclipse — the fraction of the Sun's diameter covered by the Moon at the point and moment of greatest eclipse. Values above 1 indicate a total eclipse.
const magnitude = eclipse.getMaxMagnitude();The result of the calculation should be: 1.022966
Maximum Moon/Sun ratio
Description: Returns the ratio of the apparent angular diameter of the Moon to that of the Sun at the moment of greatest eclipse. A ratio greater than 1 means totality is possible; less than 1 means an annular eclipse is possible.
const ratio = eclipse.getMaxMoonSunRatio();The result of the calculation should be: 1.045932
Maximum obscuration
Description: Returns the fraction of the Sun's area obscured by the Moon at greatest eclipse, as a value between 0 and 1. Returns 1 for total eclipses.
const obscuration = eclipse.getMaxObscuration();The result of the calculation should be: 1
Umbra path width
Description: Returns the width of the path of totality (or annularity) at greatest eclipse, in meters — the width of the band swept by the Moon's umbra (or antumbra) across Earth's surface. The band widens as the Sun sinks toward the horizon. Returns 0 for partial eclipses, where the shadow axis never reaches the ground.
const pathWidthMeters = eclipse.getUmbraPathWidth();The result of the calculation should be: 200867.2
Maximum duration
Description: Returns the total duration of the eclipse in seconds at the point of greatest eclipse, measured from first contact (C1) to last contact (C4).
const durationSeconds = eclipse.getMaxDuration();The result of the calculation should be: 11847.3
Maximum central duration
Description: Returns the duration of the central phase (totality or annularity) in seconds at the point of greatest eclipse, measured from second contact (C2) to third contact (C3).
const centralDurationSeconds = eclipse.getMaxCentralDuration();The result of the calculation should be: 272.8
Shadow geometry
Description: The following methods trace the Moon's shadow across Earth's surface: the central line, the umbra (path of totality/annularity), the penumbra (region of partial visibility), and the sunrise/sunset boundary loops. They all accept the same optional ShadowPathOptions object:
stepsInSeconds(default:10) — the time resolution in seconds between sampled points; smaller values produce a denser, more precise path. Ignored by the sunrise/sunset boundary polygons, which use a fixed internal resolution.refraction(default:false) — the horizon convention used for the endpoints. Whenfalse, the geometric horizon (Sun altitude 0°) is used. Whentrue, the standard rise/set horizon (−50′, i.e. 34′ atmospheric refraction plus the Sun's 16′ semidiameter) is used, so the path reaches slightly further to where the Sun is still visible at the horizon.
Central line
Returns the path of the central eclipse (totality or annularity) as an array of {lat, lon} coordinate objects in decimal degrees. Points are computed by stepping through the eclipse duration and projecting the Moon's shadow axis onto Earth's surface, ending exactly where the axis crosses the horizon. Points where the shadow axis misses Earth are omitted.
const path = eclipse.getCentralLine();
// [{lat: ..., lon: ...}, ...]
// Higher resolution (1-second steps)
const densePath = eclipse.getCentralLine({stepsInSeconds: 1});Umbra path polygon
Returns the path of totality (or annularity) as a single closed polygon — the region ever covered by the Moon's umbra while the Sun stands above the horizon, matching the umbral shading on eclipse maps. The result is an array of {lat, lon} coordinate objects in decimal degrees whose first and last points are identical, so the ring is closed. Returns an empty array for a purely partial eclipse, where the umbra never touches the surface.
const polygon = eclipse.getUmbraPathPolygon();
// [{lat: ..., lon: ...}, ..., {lat: ..., lon: ...}] — first point equals lastThe closed ring is ready to draw on a map or to run a point-in-polygon test against to check whether a location lies within the path of totality.
Penumbra path polygon
Returns the region of the partial eclipse as a single closed polygon — the area where any part of the eclipse is visible (the Moon's penumbra touches the ground) while the Sun stands above the horizon. The result is an array of {lat, lon} coordinate objects in decimal degrees whose first and last points are identical, so the ring is closed.
const polygon = eclipse.getPenumbraPathPolygon();
// [{lat: ..., lon: ...}, ..., {lat: ..., lon: ...}] — first point equals lastSunrise / sunset boundary polygons
Return the rise/set boundary curves shown on eclipse maps — the closed loops enclosing the region where the eclipse is already in progress as the Sun rises or sets. getSunriseBoundaryPolygon traces the sunrise side, getSunsetBoundaryPolygon the sunset side. Each result is an array of {lat, lon} coordinate objects in decimal degrees whose first and last points are identical, so the ring is closed. Only the refraction option applies here; stepsInSeconds is ignored. For an eclipse whose penumbra never fully leaves the day/night terminator both halves form a single loop, which is returned on one side while the other side is an empty array.
const sunrisePolygon = eclipse.getSunriseBoundaryPolygon();
const sunsetPolygon = eclipse.getSunsetBoundaryPolygon();
// [{lat: ..., lon: ...}, ..., {lat: ..., lon: ...}] — first point equals lastLocal eclipse for an observer
Description: Returns a LocalSolarEclipse instance for a specific observer location. Use this to calculate contact times, local eclipse type, magnitude, and obscuration as seen from that location.
import {Location} from '@astronomy-bundle/core';
const location = Location.create(21.52854, 39.14387, 6);
const localEclipse = eclipse.getLocalEclipse(location);LocalSolarEclipse (Eclipse + Location)
LocalSolarEclipse represents a solar eclipse as seen from a specific observer location. It provides contact times, local eclipse type, magnitude, obscuration, and duration for that observer.
Example: Annular solar eclipse on 1 September 2016, observer on Réunion (−21.32947°N, 55.45174°E, 43 m)
import {Location} from '@astronomy-bundle/core';
import {SolarEclipse} from '@astronomy-bundle/solar-eclipse';
import {Catalogue} from '@astronomy-bundle/solar-eclipse/catalogue';
const location = Location.create(-21.32947, 55.45174, 43);
const elements = Catalogue.getBesselianElements('2016-09-01');
const localEclipse = SolarEclipse
.createFromBesselianElements(elements)
.getLocalEclipse(location);Local eclipse type
Description: Returns the local eclipse type as a LocalSolarEclipseType value. Possible values are 'partial', 'total', and 'annular'.
const type = localEclipse.getType();The result of the calculation should be: annular
Contact times as τ offsets
Description: Returns the contact times as dimensionless time offsets (τ) relative to t0 in the Besselian elements. c1 and c4 are always present; c2 and c3 are only set for central (total or annular) eclipses and are null for partial eclipses. max is the moment of greatest eclipse at this location.
const contacts = localEclipse.getContactTaus();
const {c1, c2, max, c3, c4} = contacts;The result of the calculation should be:
c1: -0.587742
c2: 1.161350
max: 1.185225
c3: 1.20914
c4: 2.730088
Contact times
Description: Returns the contact times as TimeOfInterest objects in Terrestrial Time (TT). c1 is first external contact, c2 second contact (start of central phase), max is greatest eclipse, c3 third contact (end of central phase), and c4 last external contact. c2 and c3 are null for partial eclipses.
const contacts = localEclipse.getContactTimes();
const {year: y1, month: mo1, day: d1, hour: h1, min: m1, sec: s1} = contacts.c1.getTime();
const {year: y2, month: mo2, day: d2, hour: h2, min: m2, sec: s2} = contacts.c2.getTime();
const {year: ym, month: mom, day: dm, hour: hm, min: mm, sec: sm} = contacts.max.getTime();
const {year: y3, month: mo3, day: d3, hour: h3, min: m3, sec: s3} = contacts.c3.getTime();
const {year: y4, month: mo4, day: d4, hour: h4, min: m4, sec: s4} = contacts.c4.getTime();The result of the calculation should be:
c1: 2016-09-01 08:23:35
c2: 2016-09-01 10:08:32
max: 2016-09-01 10:09:58
c3: 2016-09-01 10:11:24
c4: 2016-09-01 11:42:39
Maximum magnitude
Description: Returns the eclipse magnitude at greatest local eclipse — the fraction of the Sun's diameter covered by the Moon at the observer's location. Values below 1 indicate a partial or annular eclipse; values above 1 indicate totality.
const magnitude = localEclipse.getMaxMagnitude();The result of the calculation should be: 0.980734
Maximum Moon/Sun ratio
Description: Returns the ratio of the apparent angular diameter of the Moon to that of the Sun at the moment of greatest local eclipse. A ratio below 1 means an annular eclipse is possible; above 1 means totality is possible.
const ratio = localEclipse.getMaxMoonSunRatio();The result of the calculation should be: 0.970421
Maximum obscuration
Description: Returns the fraction of the Sun's area obscured by the Moon at greatest local eclipse, as a value between 0 and 1. Returns 1 for total eclipses; less than 1 for annular and partial eclipses.
const obscuration = localEclipse.getMaxObscuration();The result of the calculation should be: 0.941717
Umbra path width
Description: Returns the width of the path of totality (or annularity) at the observer's location, in meters — the width of the band swept by the Moon's umbra (or antumbra) as it passes the observer at greatest local eclipse. The band widens as the Sun sinks toward the horizon, so the value can differ from the eclipse's maximum width. Returns 0 when the observer sees only a partial eclipse.
const pathWidthMeters = localEclipse.getUmbraPathWidth();The result of the calculation should be: 108317.1
Duration
Description: Returns the total duration of the eclipse in seconds at the observer's location, measured from first contact (C1) to last contact (C4).
const durationSeconds = localEclipse.getDuration();The result of the calculation should be: 11944.2
Central duration
Description: Returns the duration of the central phase (totality or annularity) in seconds at the observer's location, measured from second contact (C2) to third contact (C3). Returns 0 for partial eclipses.
const centralDurationSeconds = localEclipse.getCentralDuration();The result of the calculation should be: 172.0
Circumstances at a given time
Description: Returns a LocalEclipseCircumstances instance for a specific moment in time at the observer's location. Use this to query eclipse state (type, magnitude, obscuration) at any point during the eclipse.
import {TimeOfInterest} from '@astronomy-bundle/core';
const toi = TimeOfInterest.fromTime(2016, 9, 1, 10, 9, 58);
const circumstances = localEclipse.getCircumstances(toi);LocalEclipseCircumstances (Eclipse + Location + Time)
LocalEclipseCircumstances represents the eclipse conditions at a specific geographic location and moment in time. It requires a BesselianElements object (describing the eclipse), a Location, and a TimeOfInterest.
Example: Total solar eclipse on 2 August 2027, observer in Jeddah, Saudi Arabia (21.52854°N, 39.14387°E, 6 m)
import {TimeOfInterest, Location} from '@astronomy-bundle/core';
import {SolarEclipse} from '@astronomy-bundle/solar-eclipse';
import {Catalogue} from '@astronomy-bundle/solar-eclipse/catalogue';
const location = Location.create(21.52854, 39.14387, 6);
const toiPartial = TimeOfInterest.fromTime(2027, 8, 2, 10, 1, 5);
const toiTotal = TimeOfInterest.fromTime(2027, 8, 2, 10, 23, 13);
const elements = Catalogue.getBesselianElements('2027-08-02');
const localEclipse = SolarEclipse
.createFromBesselianElements(elements)
.getLocalEclipse(location);
// Local circumstances during partial phase in Jeddah
const circumstancesPartial = localEclipse.getCircumstances(toiPartial);
// Local circumstances during total phase in Jeddah
const circumstancesTotal = localEclipse.getCircumstances(toiTotal);Eclipse type at a given moment
Description: Returns the eclipse type at the observer's location for the given moment. Possible values are 'none', 'partial', 'total', and 'annular'. Returns 'none' before the eclipse has started or after it has ended.
Example: Get eclipse type during partial and total phases
const typePartial = circumstancesPartial.getEclipseType();
const typeTotal = circumstancesTotal.getEclipseType();The result of the calculation should be:
During partial phase: partial
During total phase: total
Eclipse in progress
Description: Returns true if any eclipse is in progress at the given moment (partial, total, or annular phase). Returns false before first contact and after last contact.
Example: Check whether the eclipse is in progress
const inEclipsePartial = circumstancesPartial.isInEclipse();
const inEclipseTotal = circumstancesTotal.isInEclipse();The result of the calculation should be:
During partial phase: true
During total phase: true
Central eclipse in progress
Description: Returns true only during the central phase — totality or annularity. Returns false during the partial phase, before first contact, and after last contact.
Example: Check whether totality (or annularity) is in progress
const inCentralPartial = circumstancesPartial.isInCentralEclipse();
const inCentralTotal = circumstancesTotal.isInCentralEclipse();The result of the calculation should be:
During partial phase: false
During total phase: true
Umbra shadow outline
Description: Returns the instantaneous outline of the Moon's umbra — or the antumbra, for annular eclipses — projected onto Earth's surface at this moment: the actual shadow footprint at that instant, as opposed to the full swept band returned by getUmbraPathPolygon. The result is an array of {lat, lon} coordinate objects in decimal degrees tracing the shadow edge, ready to draw on a map. Returns null when the observer is not within the central shadow at this moment, so any partial-phase or pre/post-eclipse moment yields no footprint.
It accepts the same refraction option as the shadow geometry methods:
refraction(default:false) — the horizon convention used to clip the footprint. Whenfalse, the geometric horizon (Sun altitude 0°) is used. Whentrue, the standard rise/set horizon (−50′) is used, so a footprint touching the horizon reaches slightly further to where the Sun is still visible. It only makes a difference when the shadow is near the horizon; for a high Sun both conventions give the same outline.
Example: Get the umbra footprint during the total and partial phases in Jeddah
const outlineTotal = circumstancesTotal.getUmbraShadowOutline();
const outlinePartial = circumstancesPartial.getUmbraShadowOutline();
// outlineTotal: [{lat: ..., lon: ...}, ...] — traces the umbra footprint enclosing the observer
// outlinePartial: null — the observer is outside the umbra during the partial phase
// Refraction-corrected horizon
const outlineRefracted = circumstancesTotal.getUmbraShadowOutline({refraction: true});Magnitude
Description: Returns the eclipse magnitude — the fraction of the Sun's diameter covered by the Moon. During the partial phase the value is between 0 and 1; it exceeds 1 during totality and is negative before the eclipse begins.
Example: Get magnitude during partial and total phases
const magnitudePartial = circumstancesPartial.getMagnitude();
const magnitudeTotal = circumstancesTotal.getMagnitude();The result of the calculation should be:
During partial phase: 0.737313
During total phase: 1.011516
Obscuration
Description: Returns the fraction of the Sun's area obscured by the Moon, as a value between 0 and 1. Unlike magnitude, this is an area-based measure and never exceeds 1. Returns 0 when no eclipse is in progress and 1 during totality.
Example: Get obscuration during partial and total phases
const obscurationPartial = circumstancesPartial.getObscuration();
const obscurationTotal = circumstancesTotal.getObscuration();The result of the calculation should be:
During partial phase: 0.684313
During total phase: 1
Geometric topocentric horizontal coordinates
Description: Returns the geometric topocentric horizontal coordinates of the Sun for the observer's location and given moment. The result contains azimuth and altitude in degrees, plus radiusVector set to 0.
Example: Get geometric Sun coordinates during totality
const horizontal = circumstancesTotal.getTopocentricHorizontalCoordinates();The result of the calculation should be:
Azimuth: 255.664319°
Geometric altitude: 76.861319°
Apparent topocentric horizontal coordinates
Description: Returns the apparent topocentric horizontal coordinates of the Sun for the observer's location and given moment. The altitude includes atmospheric refraction correction; azimuth and radiusVector are unchanged from the geometric coordinates.
Example: Get refraction-corrected Sun coordinates during totality
const apparentHorizontal = circumstancesTotal.getApparentTopocentricHorizontalCoordinates();The result of the calculation should be:
Azimuth: 255.664319°
Apparent altitude (with refraction): 76.865248°
