Time scales, conversions, and calendar utilities for astronomical calculations.
Moments
A moment is the primary internal time representation used throughout
Astro. It is a floating-point number of days since the Gregorian epoch
(0000-01-01 00:00:00 UTC). The integer part identifies the calendar day;
the fractional part represents the elapsed fraction of that day since
midnight.
The public API in Astro accepts Date and DateTime parameters and
converts them to moments before delegating to the implementation modules
(Astro.Solar, Astro.Lunar, Astro.Solar.SunRiseSet,
Astro.Lunar.MoonRiseSet). Those modules work primarily with moments
and aim to never convert back to Date or DateTime internally for
performance reasons.
Use date_time_to_moment/1 to convert a Date or DateTime to a
moment, and date_time_from_moment/1 to convert a moment back to a
UTC DateTime.
Time scales
Six time scales appear in astronomical calculations. Each serves a different purpose.
Universal Time (UTC)
The civil clock time standard. UTC is kept within one second of mean solar time at 0° longitude by the occasional insertion of leap seconds. It is the base time scale for moments: a moment is always in UTC.
See: universal_from_local/2, universal_from_standard/2,
universal_from_dynamical/1.
Standard Time
UTC adjusted for a named time zone (e.g. "America/New_York"),
including any daylight-saving offset. Standard time has discrete zone
boundaries and changes at politically determined transition points.
See: standard_from_universal/2, universal_from_standard/2.
Local (Mean Solar) Time
UTC adjusted purely by geographic longitude — what a sundial reads.
The offset is longitude / 360 of a day, a smooth function of
position with no zone boundaries or daylight-saving rules.
See: local_from_universal/2, universal_from_local/2.
Dynamical Time
The uniform time scale used for computing planetary and lunar orbits. In Astro, "dynamical time" refers to TDB (Barycentric Dynamical Time) — the time argument expected by JPL ephemerides.
Two representations coexist:
Moment-domain —
dynamical_from_universal/1adds ΔT (as a fraction of a day) to a UTC moment, producing a dynamical moment used by the Meeus-era polynomial series viajulian_centuries_from_moment/1.Seconds-past-J2000.0 —
dynamical_time_from_moment/1converts a UTC moment to TDB seconds past J2000.0, the scale used directly by the SPK kernel.dynamical_time_to_moment/1inverts it.
Both representations derive ΔT from the unified delta_t/1 function.
Terrestrial Time (TT)
A uniform atomic time scale defined on Earth's geoid, the modern successor to Ephemeris Time (ET). TT is related to International Atomic Time (TAI) by a fixed offset: TT = TAI + 32.184 s. For solar-system calculations at Earth's distance, TT ≈ TDB to within ~1.7 ms, and Astro treats them as identical.
The DateTime conversion utc_date_time_from_dynamical_date_time/1
delegates to universal_from_dynamical/1 internally.
Sidereal Time
Measures Earth's rotation relative to the stars rather than the Sun. A sidereal day is ~3 minutes 56 seconds shorter than a solar day. Greenwich Mean Sidereal Time (GMST) is used to convert between equatorial coordinates and the local horizon; Greenwich Apparent Sidereal Time (GAST) adds the equation of the equinoxes (nutation in right ascension).
Functions: greenwich_mean_sidereal_time/1,
local_sidereal_time/2, mean_sidereal_from_moment/1,
apparent_sidereal_from_moment/1. See also Astro.Coordinates.gast/1.
Time scale conversion table
The table below shows how to convert from one time scale (row) to another (column). Each cell describes the conversion algorithm. A dash (—) marks the identity diagonal.
| From \ To | Universal (UTC) | Standard | Local | Dynamical | Terrestrial | Sidereal |
|---|---|---|---|---|---|---|
| Universal (UTC) | — | + zone offset | + longitude/360 | + ΔT | + ΔT (≈ dynamical) | GMST polynomial in UTC |
| Standard | − zone offset | — | − zone + long/360 | − zone + ΔT | − zone + ΔT | via UTC then GMST |
| Local | − longitude/360 | − long/360 + zone | — | − long/360 + ΔT | − long/360 + ΔT | via UTC then GMST |
| Dynamical | − ΔT | − ΔT + zone | − ΔT + long/360 | — | identity (≈) | via UTC then GMST |
| Terrestrial | − ΔT (≈ dyn) | − ΔT + zone | − ΔT + long/360 | identity (≈) | — | via UTC then GMST |
| Sidereal | not invertible† | not invertible† | not invertible† | not invertible† | not invertible† | — |
Notes:
- zone offset = UTC offset + DST offset for the named time zone,
looked up via the configured
TimeZoneDatabase. - longitude/360 = fraction of a day corresponding to the observer's geographic longitude (west negative).
- ΔT = TT − UTC in seconds, converted to fractional days by
dividing by 86400. Computed by
delta_t/1. - Terrestrial ≈ Dynamical: TT and TDB differ by at most ~1.7 ms; Astro treats them as identical.
- † Sidereal → other: sidereal time is not uniquely invertible because multiple UTC instants map to the same sidereal angle within a sidereal day. In practice, sidereal time is computed from UTC for a known date, not converted back.
ΔT
ΔT (TT − UTC) is the difference between the uniform dynamical time
scale and civil clock time. It varies as Earth's rotation rate changes
due to tidal friction and other geophysical effects. The unified
delta_t/1 function returns ΔT in seconds for a given decimal year,
drawing on IERS observations (1972–2025), the Meeus biennial table
(1620–1971), and polynomial approximations for earlier and later dates.
Julian day system
The Julian day system provides a continuous day count independent of any calendar. It is the standard time-keeping framework in positional astronomy.
Julian Day (JD)
A continuous count of days (and fractions) from an epoch set at Greenwich noon on 1 January 4713 BC (Julian proleptic calendar). Day boundaries fall at noon, not midnight — JD 2451545.0 corresponds to 2000-01-01 12:00:00 TT.
Functions: julian_day_from_date/1, date_time_from_julian_days/1,
date_from_julian_days/1.
J2000.0
The standard astronomical epoch: 2000 January 1.5 TT (Julian Day 2451545.0). Precession angles, nutation series, and ephemeris polynomials are all referenced to this epoch. Dynamical time in this library is expressed as seconds past J2000.0.
Constant: j2000/0 (returns the moment for J2000.0).
Modified Julian Day (MJD)
JD − 2400000.5. This shifts the day boundary from noon to midnight and produces smaller numbers, convenient for modern dates. MJD 0 corresponds to 1858-11-17 00:00:00 UTC.
Function: mjd/1.
Julian Centuries
A Julian century is exactly 36525 days (100 Julian years of 365.25 days each). Precession and nutation polynomials are evaluated in Julian centuries from J2000.0. Two conversion paths exist:
julian_centuries_from_julian_day/1— converts a Julian day directly.julian_centuries_from_moment/1— converts a UTC moment by first applying ΔT to obtain a dynamical moment.julian_centuries_from_dynamical_time/1— converts dynamical time (seconds past J2000.0) to Julian centuries.
Summary
Types
A number of days as a float
A time of day as a float fraction of a day
A tuple of integer hours, integer minutes and integer seconds
A number of hours as a float
The float number of Julian centuries.
A float number of days since the Julian epoch.
A number of minutes as a float
A moment is a floating point representation of the fraction of a day.
Season expressed as a non-negative number that is <= 360 representing the sun angle of incidence (the angle at which the sun hits the earth).
A number of seconds as a float
A time is a floating point number of days since 0000-01-01 including the fractional part of a day.
A time zone name as a string
Functions
Returns the date for a given Julian day number.
Returns a UTC datetime by combining a date with a float number of minutes since midnight.
Returns a UTC datetime for a given Julian day number.
Returns a UTC DateTime for a given moment.
Returns a DateTime shifted to the requested time zone.
Returns a moment for a given date or datetime.
Returns ΔT (TT − UTC) in seconds for the given decimal year.
Returns the dynamical moment for a given universal (UTC) moment.
Returns dynamical time (TDB seconds past J2000.0) for a given UTC moment.
Returns a UTC moment for a given dynamical time (TDB seconds past J2000.0).
Returns the Greenwich Mean Sidereal Time (GMST) in degrees for a given datetime.
Returns a UTC datetime by combining a date with a float number of hours since midnight.
Returns the number of days for a given number of hours.
Returns an {hours, minutes, seconds} tuple for a given float
number of hours since midnight.
Returns the J2000.0 epoch as a moment (Gregorian days since 0000-01-01).
Returns Julian centuries from J2000.0 for a given dynamical time.
Returns Julian centuries from J2000.0 for a given Julian day.
Returns Julian centuries from J2000.0 for a given UTC moment.
Returns the astronomical Julian day number for a given date.
Returns the Julian day for a given number of Julian centuries from J2000.0.
Returns the local mean solar time for a given universal (UTC) moment and location.
Returns the Local Mean Time offset in seconds for a given location and time zone.
Returns the local sidereal time in degrees for a given location and datetime.
Returns the Modified Julian Day (MJD) for a given date.
Returns the time zone offset as a fraction of a day for a given instant and time zone.
Returns the local mean solar time offset from UTC as a fraction of a day for a given longitude.
Returns an {hours, minutes, seconds} tuple for a given number
of seconds since midnight.
Returns the standard time moment for a given universal (UTC) moment and time zone name or time zone offset.
Returns the universal (UTC) moment for a given dynamical moment.
Returns the universal (UTC) moment for a given local mean solar time moment and location.
Returns the universal (UTC) moment for a given standard time moment and time zone.
Returns a UTC datetime for a given dynamical time datetime.
Types
@type days() :: number()
A number of days as a float
@type fraction_of_day() :: number()
A time of day as a float fraction of a day
@type hms() :: {Calendar.hour(), Calendar.minute(), Calendar.second()}
A tuple of integer hours, integer minutes and integer seconds
@type hours() :: number()
A number of hours as a float
@type julian_centuries() :: number()
The float number of Julian centuries.
Since there are 365.25 days in a Julian year, a Julian century has 36,525 days.
@type julian_days() :: number()
A float number of days since the Julian epoch.
The current Julian epoch is defined to have been
noon on January 1, 2000. This epoch is
denoted J2000 and has the exact Julian day
number 2,451,545.0.
@type minutes() :: number()
A number of minutes as a float
@type moment() :: number()
A moment is a floating point representation of the fraction of a day.
@type season() :: Astro.angle()
Season expressed as a non-negative number that is <= 360 representing the sun angle of incidence (the angle at which the sun hits the earth).
@type seconds() :: number()
A number of seconds as a float
@type time() :: number()
A time is a floating point number of days since 0000-01-01 including the fractional part of a day.
@type zone_name() :: binary()
A time zone name as a string
Functions
Returns the date for a given Julian day number.
The Julian day is rounded to the nearest integer before conversion. This is suitable when only the calendar date is needed, without time-of-day information.
Arguments
julian_dayis a Julian day number (float or integer).
Returns
{:ok, date}— aDate.t/0.
Examples
iex> Astro.Time.date_from_julian_days(2458822.5)
{:ok, ~D[2019-12-05]}
@spec date_time_from_date_and_minutes(minutes(), Calendar.date()) :: {:ok, Calendar.datetime()}
Returns a UTC datetime by combining a date with a float number of minutes since midnight.
Arguments
minutesis a float number of minutes since midnight.dateis anyCalendar.date/0.
Returns
{:ok, datetime}— aDateTime.t/0in UTC.
Examples
iex> Astro.Time.date_time_from_date_and_minutes(720.0, ~D[2024-06-21])
{:ok, ~U[2024-06-21 12:00:00Z]}
@spec date_time_from_julian_days(julian_days()) :: {:ok, Calendar.datetime()}
Returns a UTC datetime for a given Julian day number.
Arguments
julian_dayis a Julian day number as afloat.
Returns
{:ok, datetime}— aDateTime.t/0in the UTC time zone.
Examples
iex> Astro.Time.date_time_from_julian_days(2458822.5)
{:ok, ~U[2019-12-05 00:00:00Z]}
iex> Astro.Time.date_time_from_julian_days(2451545.0)
{:ok, ~U[2000-01-01 12:00:00Z]}
@spec date_time_from_moment(moment()) :: {:ok, DateTime.t()}
Returns a UTC DateTime for a given moment.
A moment is by definition in the UTC timezone, so the returned
DateTime always has time_zone: "Etc/UTC". Microsecond
precision is preserved.
Arguments
momentis a float representation of a UTC datetime where the integer part is the number of Gregorian days since 0000-01-01 and the fractional part is the fraction of a day since midnight.
Returns
{:ok, datetime}— aDateTime.t/0in UTC with microsecond precision.
Examples
iex> Astro.Time.date_time_from_moment(740047.5)
{:ok, ~U[2026-03-07 12:00:00.000000Z]}
iex> Astro.Time.date_time_from_moment(740047.0)
{:ok, ~U[2026-03-07 00:00:00.000000Z]}
iex> Astro.Time.date_time_from_moment(740047.999999)
{:ok, ~U[2026-03-07 23:59:59.913599Z]}
Returns a DateTime shifted to the requested time zone.
Converts a UTC DateTime to the time zone specified in options.
When the time zone is :utc, the datetime is returned unchanged.
When :default, the time zone is resolved from the location using
TzWorld (or a custom :time_zone_resolver). When a time zone
name string is given, the datetime is shifted to that zone.
Arguments
utc_event_timeis a UTCDateTime.locationis aGeo.PointZstruct with{longitude, latitude, altitude}coordinates. Used only when:time_zoneis:default.optionsis a map containing::time_zone—:utc,:default, or a time zone name string.:time_zone_database— the time zone database module (e.g. Tz.TimeZoneDatabase).:time_zone_resolver— (optional) a 1-arity function(%Geo.Point{}) → {:ok, String.t()}for custom zone resolution.
Returns
{:ok, datetime}— theDateTimein the requested time zone.{:error, reason}— if the time zone cannot be resolved or shifted.
Examples
iex> utc = ~U[2024-06-21 12:00:00Z]
iex> location = %Geo.PointZ{coordinates: {0.0, 51.5, 0.0}}
iex> options = %{time_zone: :utc, time_zone_database: Tz.TimeZoneDatabase}
iex> Astro.Time.date_time_in_requested_zone(utc, location, options)
{:ok, ~U[2024-06-21 12:00:00Z]}
@spec date_time_to_moment(Calendar.date() | Calendar.datetime()) :: moment()
Returns a moment for a given date or datetime.
A moment is a float where the integer part is the number of Gregorian days since 0000-01-01 and the fractional part is the fraction of a day since midnight. Moments are always in UTC.
When given a DateTime, it is first shifted to UTC before conversion.
When given a Date, returns the integer Gregorian day number
(midnight UTC).
Arguments
date_or_datetimeis anyCalendar.date/0orCalendar.datetime/0.
Returns
- A moment as a
float(or integer forDateinputs).
Examples
iex> Astro.Time.date_time_to_moment(~U[2026-03-07 12:00:00Z])
740047.5
iex> Astro.Time.date_time_to_moment(~D[2026-03-07])
740047
Returns ΔT (TT − UTC) in seconds for the given decimal year.
ΔT is the difference between Terrestrial Time (TT) and Universal Time (UTC). It varies over time as Earth's rotation rate changes.
Uses the best available data for each era:
- 1972–2025: IERS-observed annual values with linear interpolation
- 1620–1971: Meeus biennial lookup table with interpolation
- Pre-1620 and post-2025: Polynomial approximations
Arguments
yearis a decimal year (e.g., 2024.5 for mid-2024)
Returns
- ΔT in seconds as a
float.
Examples
iex> Astro.Time.delta_t(2000.0)
63.83
iex> Float.round(Astro.Time.delta_t(2024.5), 2)
69.24
Returns the dynamical moment for a given universal (UTC) moment.
Adds ΔT (converted to a fraction of a day) to the UTC moment,
producing a dynamical moment suitable for evaluating Meeus-era
polynomial series via julian_centuries_from_moment/1.
Arguments
tis a moment (float Gregorian days since 0000-01-01) in UTC.
Returns
- A moment in the dynamical time scale (float Gregorian days).
Examples
iex> t = Astro.Time.date_time_to_moment(~U[2000-01-01 12:00:00Z])
iex> dt = Astro.Time.dynamical_from_universal(t)
iex> Float.round(dt - t, 6)
0.000739
Returns dynamical time (TDB seconds past J2000.0) for a given UTC moment.
Applies a date-dependent ΔT via delta_t/1 to convert the UTC
moment to TDB, the time scale expected by the JPL SPK ephemeris
kernel.
Arguments
momentis a moment (float Gregorian days since 0000-01-01) in UTC.
Returns
- Dynamical time as a
float(TDB seconds past J2000.0).
Examples
iex> t = Astro.Time.date_time_to_moment(~U[2000-01-01 12:00:00Z])
iex> dt = Astro.Time.dynamical_time_from_moment(t)
iex> Float.round(dt, 1)
63.8
Returns a UTC moment for a given dynamical time (TDB seconds past J2000.0).
This is the inverse of dynamical_time_from_moment/1. Subtracts a
date-dependent ΔT to recover the UTC moment.
Arguments
dynamical_timeis TDB seconds past J2000.0 (float).
Returns
- A moment (float Gregorian days since 0000-01-01) in UTC.
Examples
iex> t = Astro.Time.date_time_to_moment(~U[2000-01-01 12:00:00Z])
iex> dt = Astro.Time.dynamical_time_from_moment(t)
iex> round_trip = Astro.Time.dynamical_time_to_moment(dt)
iex> Float.round(abs(round_trip - t) * 86400, 3)
0.0
@spec greenwich_mean_sidereal_time(Calendar.datetime()) :: moment()
Returns the Greenwich Mean Sidereal Time (GMST) in degrees for a given datetime.
GMST measures Earth's rotation relative to the stars. It is the hour angle of the mean vernal equinox at the Greenwich meridian.
Arguments
date_timeis anyCalendar.datetime/0. If not already in UTC, it is converted to UTC before computation.
Returns
- GMST in degrees (float, typically 0–360).
Examples
iex> gmst = Astro.Time.greenwich_mean_sidereal_time(~U[2000-01-01 12:00:00Z])
iex> Float.round(gmst, 4)
280.7273
@spec hours_and_date_to_date_time(hours(), Calendar.date()) :: {:ok, Calendar.datetime()}
Returns a UTC datetime by combining a date with a float number of hours since midnight.
Arguments
time_of_dayis a float number of hours since midnight (e.g. 13.5 for 1:30 PM).dateis anyCalendar.date/0.
Returns
{:ok, datetime}— aDateTime.t/0in UTC.
Examples
iex> {:ok, dt} = Astro.Time.hours_and_date_to_date_time(12.0, ~D[2024-06-21])
iex> DateTime.truncate(dt, :second)
~U[2024-06-21 12:00:00Z]
Returns the number of days for a given number of hours.
Arguments
hoursis a number of hours.
Returns
- The equivalent number of days as a
float.
Examples
iex> Astro.Time.hours_to_days(48)
2.0
iex> Astro.Time.hours_to_days(6)
0.25
Returns an {hours, minutes, seconds} tuple for a given float
number of hours since midnight.
Arguments
time_of_dayis a float number of hours since midnight.
Returns
- A
{hour, minute, second}tuple. Fractional seconds are truncated.
Examples
iex> Astro.Time.hours_to_hms(0.0)
{0, 0, 0}
iex> Astro.Time.hours_to_hms(23.999)
{23, 59, 56}
iex> Astro.Time.hours_to_hms(15.456)
{15, 27, 21}
Returns the J2000.0 epoch as a moment (Gregorian days since 0000-01-01).
J2000.0 is 2000 January 1.5 TT (noon on January 1, 2000). This is the standard reference epoch for precession, nutation, and ephemeris polynomials.
Returns
- The J2000.0 moment as a
float(730485.5).
Examples
iex> Astro.Time.j2000()
730485.5
Returns Julian centuries from J2000.0 for a given dynamical time.
A pure arithmetic conversion: divides TDB seconds by the number of seconds in a Julian century (36525 × 86400).
Arguments
dynamical_timeis TDB seconds past J2000.0 (float).
Returns
- Julian centuries from J2000.0 as a
float.
Examples
iex> Astro.Time.julian_centuries_from_dynamical_time(0.0)
0.0
iex> Astro.Time.julian_centuries_from_dynamical_time(36525.0 * 86400.0)
1.0
Returns Julian centuries from J2000.0 for a given Julian day.
Arguments
julian_dayis a Julian day number (float) such as returned fromjulian_day_from_date/1.
Returns
- Julian centuries from J2000.0 as a
float.
Examples
iex> Astro.Time.julian_centuries_from_julian_day(2451545.0)
0.0
iex> Float.round(Astro.Time.julian_centuries_from_julian_day(2451545.0 + 36525.0), 1)
1.0
Returns Julian centuries from J2000.0 for a given UTC moment.
First converts the UTC moment to a dynamical moment (by adding ΔT), then computes Julian centuries from J2000.0. This is the time argument expected by Meeus-era polynomial series for precession, nutation, and orbital elements.
Arguments
tis a moment (float Gregorian days since 0000-01-01) in UTC.
Returns
- Julian centuries from J2000.0 as a
float.
Examples
iex> t = Astro.Time.date_time_to_moment(~U[2000-01-01 12:00:00Z])
iex> Float.round(Astro.Time.julian_centuries_from_moment(t), 6)
0.0
@spec julian_day_from_date(Calendar.date()) :: julian_days()
Returns the astronomical Julian day number for a given date.
Arguments
dateis anyCalendar.date/0.
Returns
- The Julian day as a
float. The.5fractional part reflects the Julian day convention of starting at noon.
Examples
iex> Astro.Time.julian_day_from_date(~D[2019-12-05])
2458822.5
iex> Astro.Time.julian_day_from_date(~D[2000-01-01])
2451544.5
@spec julian_day_from_julian_centuries(julian_centuries()) :: julian_days()
Returns the Julian day for a given number of Julian centuries from J2000.0.
This is the inverse of julian_centuries_from_julian_day/1.
Arguments
julian_centuriesis a float number of Julian centuries from J2000.0.
Returns
- The Julian day as a
float.
Examples
iex> Astro.Time.julian_day_from_julian_centuries(0.0)
2451545.0
iex> Astro.Time.julian_day_from_julian_centuries(1.0)
2488070.0
@spec local_from_universal(time(), Geo.PointZ.t()) :: time()
Returns the local mean solar time for a given universal (UTC) moment and location.
Local mean solar time is UTC plus an offset derived purely from
geographic longitude (longitude / 360 of a day). This is distinct
from standard time, which uses named time zone boundaries and
daylight-saving rules.
Arguments
tis a moment (float Gregorian days since 0000-01-01) in UTC.locationis aGeo.PointZwith{longitude, latitude, altitude}.
Returns
- A moment in local mean solar time (float Gregorian days).
Examples
iex> location = %Geo.PointZ{coordinates: {-90.0, 40.0, 0.0}}
iex> t = 740047.5
iex> Astro.Time.local_from_universal(t, location)
740047.25
Returns the Local Mean Time offset in seconds for a given location and time zone.
The offset is the difference between Local Mean Time at the given longitude and Standard Time in effect for the given time zone. Local Mean Time is the solar time at a specific longitude, while Standard Time is the civil time for the time zone.
Arguments
locationis aGeo.PointZstruct with{longitude, latitude, altitude}coordinates.gregorian_secondsis the number of seconds since the Gregorian epoch (0000-01-01 00:00:00).time_zoneis a time zone name string (e.g."Etc/UTC").
Returns
- A
floatrepresenting the offset in seconds between Local Mean Time and Standard Time.
Examples
iex> location = %Geo.PointZ{coordinates: {0.0, 51.5, 0.0}}
iex> gregorian_seconds = 63_871_632_000
iex> Astro.Time.local_mean_time_offset(location, gregorian_seconds, "Etc/UTC")
0.0
@spec local_sidereal_time(Astro.location(), Calendar.datetime()) :: moment()
Returns the local sidereal time in degrees for a given location and datetime.
Local sidereal time is GMST plus the observer's geographic longitude.
Arguments
locationis anyAstro.location/0(aGeo.Point,Geo.PointZ, or{longitude, latitude}tuple).date_timeis anyCalendar.datetime/0.
Returns
- Local sidereal time in degrees (float).
Examples
iex> lst = Astro.Time.local_sidereal_time({0.0, 51.5}, ~U[2000-01-01 12:00:00Z])
iex> Float.round(lst, 4)
280.7273
@spec mjd(Calendar.date()) :: julian_days()
Returns the Modified Julian Day (MJD) for a given date.
MJD is JD − 2400000.5, shifting the day boundary from noon to midnight and producing smaller numbers. MJD 0 corresponds to 1858-11-17 00:00:00 UTC.
Arguments
dateis anyCalendar.date/0.
Returns
- The Modified Julian Day as a
float.
Examples
iex> Astro.Time.mjd(~D[2019-12-05])
58822.0
Returns the time zone offset as a fraction of a day for a given instant and time zone.
Arguments
gregorian_secondsis the number of seconds since the Gregorian epoch (0000-01-01 00:00:00).time_zoneis a time zone name string (e.g."Europe/London").time_zone_databaseis the time zone database module (defaults toCalendar.get_time_zone_database()).
Returns
The total offset (UTC offset + DST) as a fraction of a day (float).
:ambiguous_timeif the instant falls in a DST overlap.:no_such_time_or_zoneif the zone is unknown or the instant falls in a DST gap.
Examples
iex> t = Date.to_gregorian_days(~D[2021-08-01]) * (60 * 60 * 24)
iex> Astro.Time.offset_for_zone(t, "Europe/London")
{:ok, 0.041666666666666664}
@spec offset_from_longitude(Geo.PointZ.t() | Astro.longitude()) :: moment()
Returns the local mean solar time offset from UTC as a fraction of a day for a given longitude.
The offset is longitude / 360 of a day. West longitudes
(negative) produce negative offsets, east longitudes produce
positive offsets.
Arguments
longitudeis either aGeo.PointZstruct or a numeric longitude in degrees (west negative, east positive).
Returns
- The offset as a fraction of a day (float). For example, −90° returns −0.25 (6 hours behind UTC).
Examples
iex> Astro.Time.offset_from_longitude(-90.0)
-0.25
iex> Astro.Time.offset_from_longitude(180.0)
0.5
@spec seconds_to_hms(fraction_of_day()) :: hms()
Returns an {hours, minutes, seconds} tuple for a given number
of seconds since midnight.
Arguments
time_of_dayis a number of seconds since midnight.
Returns
- A
{hour, minute, second}tuple. Fractional seconds are truncated.
Examples
iex> Astro.Time.seconds_to_hms(0.0)
{0, 0, 0}
iex> Astro.Time.seconds_to_hms(3214)
{0, 53, 34}
iex> Astro.Time.seconds_to_hms(10_000)
{2, 46, 39}
Returns the standard time moment for a given universal (UTC) moment and time zone name or time zone offset.
Standard time is UTC adjusted by the named time zone's UTC offset and any daylight-saving offset in effect at the given instant.
Arguments
tis a moment (float Gregorian days since 0000-01-01) in UTC.zone_nameis either a time zone name string (e.g."America/New_York") or a numeric offset in fractional days.
Returns
- A moment in standard time (float Gregorian days).
Examples
iex> t = Astro.Time.date_time_to_moment(~U[2024-01-15 12:00:00Z])
iex> Astro.Time.standard_from_universal(t, "Australia/Sydney")
739265.9200462963
iex> t = Astro.Time.date_time_to_moment(~U[2024-01-15 12:00:00Z])
iex> standard = Astro.Time.standard_from_universal(t, 0.25)
iex> standard - t
0.25
Returns the universal (UTC) moment for a given dynamical moment.
Subtracts ΔT (converted to a fraction of a day) from a dynamical moment, recovering the corresponding UTC moment.
Arguments
tis a moment (float Gregorian days since 0000-01-01) in dynamical time.
Returns
- A moment in the UTC time scale (float Gregorian days).
Examples
iex> t = Astro.Time.date_time_to_moment(~U[2000-01-01 12:00:00Z])
iex> dyn = Astro.Time.dynamical_from_universal(t)
iex> Astro.Time.universal_from_dynamical(dyn)
730485.5
@spec universal_from_local(time(), Geo.PointZ.t()) :: time()
Returns the universal (UTC) moment for a given local mean solar time moment and location.
Subtracts the longitude-based offset (longitude / 360 of a day)
from the local time to recover UTC. This is the inverse of
local_from_universal/2.
Arguments
tis a moment (float Gregorian days since 0000-01-01) in local mean solar time.locationis aGeo.PointZwith{longitude, latitude, altitude}.
Returns
- A moment in UTC (float Gregorian days).
Examples
iex> location = %Geo.PointZ{coordinates: {-90.0, 40.0, 0.0}}
iex> local_t = 740047.25
iex> Astro.Time.universal_from_local(local_t, location)
740047.5
Returns the universal (UTC) moment for a given standard time moment and time zone.
Subtracts the time zone offset (UTC offset + DST) from the standard
time moment to recover UTC. This is the inverse of
standard_from_universal/2.
Arguments
tis a moment (float Gregorian days since 0000-01-01) in standard time.zone_nameis either a time zone name string (e.g."America/New_York") or a numeric offset in fractional days.
Returns
- A moment in UTC (float Gregorian days).
Examples
iex> t = 740047.75
iex> utc = Astro.Time.universal_from_standard(t, 0.25)
iex> t - utc
0.25
@spec utc_date_time_from_dynamical_date_time(Calendar.datetime()) :: {:ok, Calendar.datetime()}
Returns a UTC datetime for a given dynamical time datetime.
Converts a DateTime whose clock reading is in dynamical time
(TDB ≈ TT) to the corresponding UTC DateTime by subtracting
ΔT. Internally delegates to universal_from_dynamical/1.
Arguments
datetimeis aDateTimewhose clock reading is in dynamical time (TDB seconds, equivalently Terrestrial Time).
Returns
{:ok, utc_datetime}— the corresponding UTCDateTime.
Examples
iex> {:ok, dyn} = Astro.Time.date_time_from_julian_days(2451545.0)
iex> {:ok, utc} = Astro.Time.utc_date_time_from_dynamical_date_time(dyn)
iex> DateTime.truncate(utc, :second)
~U[2000-01-01 11:58:56Z]