Time and Time Scales

Conversions between the time representations TABASCAL handles: seconds, days, Julian Dates, Modified Julian Dates, Python datetime, and skyfield’s Time.

Time scales

A Julian Date is a number until a scale says what it counts, and the scales in use differ by amounts that matter. At J2000 the offsets from UTC are:

Scale

Offset from UTC

Error if a UTC epoch is read as this scale

ut1

~0.35 s (DUT1)

~2.7 km of LEO satellite ground track

tai

32 s (leap seconds)

~240 km

tt / et

64.184 s

~481 km

None of these raise; they simply produce a wrong position. Measurement Sets record which scale their TIME column uses in its MEASINFO record (Ref: UTC in the common case), so the scale should be taken from the data rather than assumed. skyfield_time() accepts it as scale, defaulting to utc.

tabascal.time.TIME_SCALES = {'et': 'tt_jd', 'iat': 'tai_jd', 'tai': 'tai_jd', 'tdb': 'tdb_jd', 'tdt': 'tt_jd', 'tt': 'tt_jd', 'ut': 'ut1_jd', 'ut1': 'ut1_jd', 'utc': '_utc_jd'}

Time scales that can be named in a Measurement Set’s TIME column MEASINFO record, mapped to the skyfield.timelib.Timescale constructor that interprets a Julian Date on that scale.

casacore names several of these more than once, and the name it writes is not always the one an outsider would reach for: its canonical spelling of Terrestrial Time is TDT, with TT and ET as synonyms, and TAI is also spelled IAT. All spellings are accepted, since the point is to forward whatever the MS declares.

tabascal.time.datetime_to_jd(dt)[source]

Naive (UTC) datetime.datetime → UTC Julian Date.

Inverse of jd_to_datetime(). A timezone-aware datetime is accepted and treated as UTC.

tabascal.time.gast_deg(times_jd, scale: str = 'utc')[source]

Greenwich Apparent Sidereal Time, in degrees, for Julian Dates.

The apparent (not mean) sidereal angle is returned, i.e. it includes the equation of the equinoxes, so this is GAST and not GMST.

Parameters:
  • times_jd (array_like) – Observation times as Julian Dates on scale.

  • scale (str, optional) – Time scale the Julian Dates are on; see skyfield_time().

Returns:

GAST in degrees.

Return type:

np.ndarray

tabascal.time.jd_to_datetime(jd)[source]

UTC Julian Date → naive (UTC) datetime.datetime.

Civil-time conversion treating UTC as a uniform day count (no leap-second handling), which is all that is needed for TLE epoch dates and timestamps.

tabascal.time.skyfield_time(times_jd, scale: str = 'utc')[source]

Julian Dates on a named time scale → skyfield.timelib.Time.

The single entry point for turning observation times into skyfield times, so the decisions below are made once rather than at each call site.

The scale is not cosmetic. A Julian Date is a number until a scale says what it counts. Reading a UTC epoch as UT1 shifts it by DUT1 (up to ~0.9 s), dragging a satellite along its track by the distance it covers in that time; reading it as TAI shifts it by the accumulated leap seconds, currently 37 s. Neither produces an error — only a wrong position.

scale defaults to "utc" because that is what a Measurement Set’s TIME column almost always declares (MEASINFO Ref: UTC). It is a default, not an assumption: an MS may declare TAI or another scale, and callers reading one should pass what it says rather than relying on this.

The Julian Date is split into whole and fractional parts before being handed to skyfield, to preserve full f64 precision: a JD’s ~2.5e6 day magnitude leaves f64 only ~5e-10 days of resolution on the value as a whole. ut1 is the exception — skyfield’s ut1_jd takes no fraction argument, so that one scale is passed the recombined Julian Date and keeps only ~5e-10 days (~40 us) of resolution.

For utc this uses skyfield’s private _utc_jd, which is why pyproject.toml pins skyfield>=1.49,<2. Keeping it to this one call site means the pin protects a single line.

Parameters:
  • times_jd (array_like) – Observation times as Julian Dates on scale.

  • scale (str, optional) – Time scale the Julian Dates are on, as named in an MS MEASINFO record. One of TIME_SCALES; case-insensitive. Defaults to "utc".

Returns:

The same times, read on scale.

Return type:

skyfield.timelib.Time

Raises:

ValueError – If scale is not one tabascal can interpret.

tabascal.time.timescale()[source]

The skyfield timescale, built once and reused.