Time#

class spacekernel.time.Time(data: DatetimeLike, str scale: str = 'UTC', str format: str | None = None)#

Bases: object

Mission-designed Time objects for Earth satellites.

The main purpose of Time is to provide a friendly and rapid interface for creating, handling and converting large arrays of time samples between time scales and formats (refer to [1]).

Time is able to deal with time samples observed with respect to the most relevant time scales for Earth satellite missions: TAI, UTC, UT1, and TT . The time scale of an instance is accessed through the read-only attribute scale.

In order to provide compatibility with the most traditional time types, Time accepts several constructing possibilities.

REVIEW

For such reason, Time is built as an extension type that implements the buffer protocol, hence behaving like a numpy's array in several situations.

Nevertheless, it may become a bit confusing learn all possible instantiating signatures just by refering to the parameters description. Hence, to easy such learning process, the tutorial tutorial-time provides a collection of comprehensive examples on how to create Time objects.

Time is mostly focused on providing high performance time services for space mission simulations and analysis rather than being an all-purpose time class.

Time can be represented in python in many types: str, datetime, datetime64, DatetimeIndex, Astropy's Time, etc. In order to provide compatibility with the most common types and, consequently, a friendly interface to them, Time accepts several constructing possibilities. Nevertheless, it may become a bit confusing learn all possible instantiating signatures just by refering to the parameters description. Hence, to easy such learning process, the tutorial tutorial-time provides a collection of comprehensive examples on how to create Time objects.

Parameters:
datadatetime-like object. Following options are available:
jd12(N,2)-shaped float64-dtyped ndarray

Two-part julian date (used by SOFA). Parameter format is ignored.

jd(N,)-shaped float64-dtyped ndarray

Julian date. Parameter format must be set to 'jd'.

mjd(N,)-shaped float64-dtyped ndarray

Modified julian date. Parameter format must be set to 'mjd'.

jyear(N,)-shaped float64-dtyped ndarray

Years with respect to the Julian epoch. Parameter format must be set to 'jyear'.

byear(N,)-shaped float64-dtyped ndarray

Years with respect to the besselian epoch. Parameter format must be set to 'byear'.

dtf(N,)-shaped Structured array

Datetime fields. This array must have the following structured datatype:

dtype=[
    ('year', numpy.uint16),
    ('month', numpy.uint8),
    ('day', numpy.uint8),
    ('hour', numpy.uint8),
    ('minute', numpy.uint8),
    ('second', numpy.double)
]

Parameter format is ignored.

datetime64datetime64 | (N,)-shaped datetime64-dtyped ndarray

Numpy datetime object. Parameter format is ignored.

int64int64 | (N,)-shaped int64-dtyped ndarray

Nanoseconds since 1970-01-01 00:00:00. Parameter format is ignored.

pandasTimestamp | DatetimeIndex

Pandas datetime objects. Parameter format is ignored. If it is timezone-aware, then it will first be converted to UTC and scale parameter is ignored.

pydatetimedatetime | Iterator [datetime]

Python datetime object. Parameter format is ignored. If it is timezone-aware, then it will first be converted to UTC and scale parameter is ignored.

datetimeisostr | Iterator [str]

ISO 8601 strings. Parameter format is ignored. If it is timezone-aware, then it will first be converted to UTC and scale parameter is ignored.

astropyastropy.time.Time

Astropy datetime object. Parameters format and scale are ignored.

spacekernelTime

SpaceKernel datetime object. This is usually done to get a copy of the original object. Parameters format and scale are ignored.

scalestr

The time scale of the time samples. Possible values are: 'TAI', 'TT', 'UTC', 'UT1'.

formatstr | None

Format of the data. If the format could not be unambiguously inferred from data, then this parameter must be set.

References

Array Interface#

The Time class implements a NumPy/Pandas-compatible array interface, supporting element-wise arithmetic, rich comparisons, indexing, slicing, and seamless conversion to NumPy and pandas objects.

Rich Comparisons#

Time instances may be compared directly against pandas timestamps, NumPy datetime arrays, or scalar date/time strings. All comparison operators return a boolean array of the same length.

>> from pandas import date_range
>> from spacekernel.time import Time

>> time = Time.range(start='2021-03-18', end='2022-10-18', step=3600)
>> time_pd = date_range(start='2021-03-18',
                        end='2022-10-18', freq='3600s')
>> time_np = time_pd.to_numpy()

>> time == time_pd  # can be compared to DatetimeIndex or Timestamp
[ True  True  True ...  True  True  True]

>> time == time_np  # can be compared to numpy's datetime64
[ True  True  True ...  True  True  True]

>> time == Time(time_np) # can be compared to other Time instances
[ True  True  True ...  True  True  True]

>> time > '2022-05-10'  # can be compared to iso-format strings
[False False False ...  True  True  True]

Indexing & Slicing#

Supports basic indexing, slicing, boolean masking, and advanced integer indexing, producing new Time instances that mirror Pandas behavior.

single index#
>> time[-5]

Time(2022-10-17T20:00:00.000000000, scale=UTC)
multiple index#
>> time[[0, 10, 20]]

Time(['2021-03-18T00:00:00.000000000' '2021-03-18T10:00:00.000000000'
 '2021-03-18T20:00:00.000000000'], scale=UTC)
Slicing by index#
>> time[100:-100:3]

Time(['2021-03-22T04:00:00.000000000' '2021-03-22T07:00:00.000000000'
 '2021-03-22T10:00:00.000000000' ... '2022-10-13T13:00:00.000000000'
 '2022-10-13T16:00:00.000000000' '2022-10-13T19:00:00.000000000'], scale=UTC)
Slicing by value#
>> time['2021-08':'2022-03']

Time(['2021-08-01T00:00:00.000000000' '2021-08-01T01:00:00.000000000'
 '2021-08-01T02:00:00.000000000' ... '2022-02-28T21:00:00.000000000'
 '2022-02-28T22:00:00.000000000' '2022-02-28T23:00:00.000000000'], scale=UTC)

Elementwise Arithmetic#

The Time class supports element‐wise addition and subtraction via its dunder methods, accepting scalar, string, or array offsets and returning either a new Time or a numeric array:

Time.__add__(other) Time

Add an offset to each timestamp in the sequence.

Parameters other (numbers.Real or numpy.ndarray of float or str) – A scalar number of seconds; a NumPy array of seconds; or a string with a time unit suffix (e.g. “s”, “min”, “h”, “d”, “y”).

Returns A new Time instance shifted by the specified amount(s), preserving the original shape and time scale.

Time.__radd__(other) Time

Right‐hand addition (i.e. when the left operand is non‐Time). Delegates to __add__().

Time.__sub__(other) Union[:class:`Time`, :class:`numpy.ndarray`]

Subtract either another Time or an offset:

  • If other is a Time, returns a NumPy array of float differences in seconds (element‐wise).

  • If other is a scalar, string, or NumPy float array, returns a new Time shifted by the negative of those offsets.

Time.__isub__(other) Time

In‐place subtraction. Equivalent to self = self - other.

Time.__rsub__(other) Union[:class:`Time`, :class:`numpy.ndarray`]

Right‐hand subtraction. If other is a scalar or array, computes other - self; if other is a Time, equivalent to __sub__().

Supported string units s, sec (seconds) min (minutes) h (hours) d (days) y (Julian years)

All arithmetic preserves high‐precision nanosecond timing under the hood and propagates the scale unchanged.

Summary#

Time.scale

Time.scale: str Timescale of the samples

Time.to_scale(self, str scale)

Convert this Time instance to a different time scale.

Time.tai

Time.tai: Time The corresponding Time instance converted to TAI scale

Time.tt

Time.tt: Time The corresponding Time instance converted to TT scale

Time.utc

Time.utc: Time The corresponding Time instance converted to UTC scale

Time.ut1

Time.ut1: Time The corresponding Time instance converted to UT1 scale

Time.jd12

Time.jd12: ndarray[double] Two-part julian date used by SOFA

Time.jd

Time.jd: ndarray[double] Julian date

Time.mjd

Time.mjd: ndarray[double] Modified Julian date

Time.jyear

Time.jyear: ndarray[double] Years with respect to the Julian epoch

Time.byear

Time.byear: ndarray[double] Years with respect to the Besselian epoch

Time.dtf

Time.dtf: ndarray[DTF] Datetime fields

Time.datetime64

Time.datetime64: ndarray[npy_datetime] Numpy's datetime64

Time.int64

Time.int64: ndarray[int64_t] Nanoseconds since 1970-01-01 00:00:00

Time.range(cls[, scale])

Construct a Time object spanning a regular grid of instants.

Time.steps

Time.steps: ndarray[double] Compute time intervals between consecutive entries, in seconds.

Time.to_astropy(self)

Convert this Time to an Astropy Time object.

Time.to_pandas(self)

Convert this Time to a pandas DatetimeIndex or Timestamp.

Time.now(cls)

Construct a Time for the current UTC instant.

Time.ut1_utc

Time.ut1_utc: ndarray[double] The difference UT1-UTC, a.k.a \(\Delta UT\) or \(\Delta UT1\) (in seconds)

Time.ut1_tai

Time.ut1_tai: ndarray[double] The difference UT1-TAI (in seconds)

Time.tt_ut1

Time.tt_ut1: ndarray[double] The difference TT-UT1, a.k.a \(\Delta T\) (in seconds)

Time.tai_utc

Time.tai_utc: ndarray[double] The difference TAI-UTC, a.k.a \(\Delta AT\) (in seconds)

Members#

Time.scale#

Time.scale: str Timescale of the samples

Time.tai#

Time.tai: Time The corresponding Time instance converted to TAI scale

Time.tt#

Time.tt: Time The corresponding Time instance converted to TT scale

Time.utc#

Time.utc: Time The corresponding Time instance converted to UTC scale

Time.ut1#

Time.ut1: Time The corresponding Time instance converted to UT1 scale

Time.to_scale(self, str scale) Time#

Convert this Time instance to a different time scale.

Parameters:
scale{‘TAI’, ‘TAI’, ‘UT1’, ‘UTC’}

The target time scale:

  • ‘TAI’ : International Atomic Time

  • ‘TT’ : Terrestrial Time

  • ‘UT1’ : Universal Time 1

  • ‘UTC’ : Coordinated Universal Time

Returns:
Time

A new Time object representing the same physical instant expressed in the requested scale.

Raises:
ValueError

If scale is not one of ‘TAI’, ‘TT’, ‘UT1’, or ‘UTC’.

Examples

>>> t_tt = time_obj.to_scale('TT')
>>> t_utc = t_tt.to_scale('UTC')
Time.jd12#

Time.jd12: ndarray[double] Two-part julian date used by SOFA

Time.jd#

Time.jd: ndarray[double] Julian date

Time.mjd#

Time.mjd: ndarray[double] Modified Julian date

Time.jyear#

Time.jyear: ndarray[double] Years with respect to the Julian epoch

Julian epoch = 2000-01-01 12:00:00 TT Julian year = 365.25 days

Time.byear#

Time.byear: ndarray[double] Years with respect to the Besselian epoch

Besselian epoch = ??? Besselian year = 365.2422 days

Time.dtf#

Time.dtf: ndarray[DTF] Datetime fields

Time.datetime64#

Time.datetime64: ndarray[npy_datetime] Numpy’s datetime64

Time.int64#

Time.int64: ndarray[int64_t] Nanoseconds since 1970-01-01 00:00:00

classmethod Time.range(cls, scale='UTC', **kwargs) Time#

Construct a Time object spanning a regular grid of instants.

This is a thin wrapper around pandas.date_range, with added support for Time inputs and numeric step definitions (in seconds).

Parameters:
scale{‘UTC’, ‘TAI’, ‘TT’, ‘UT1’}, optional

Time scale for the resulting Time object (default: ‘UTC’).

startstr, pandas.Timestamp, or Time, optional

Left endpoint of the range. If a Time is passed, its value is converted to a plain pandas timestamp.

endstr, pandas.Timestamp, or Time, optional

Right endpoint of the range. Converted to pandas timestamp if needed.

stepstr or float, optional

If a string, passed directly as freq to pandas.date_range (e.g. ‘1H’, ‘30T’). If a real number, interpreted as a fixed step size in seconds.

n_pointsint, optional

Number of periods; shorthand for periods in pandas.

**kwargs

Any other keyword arguments accepted by pandas.date_range (e.g. freq, periods, tz, inclusive, etc.).

Returns:
Time

A new Time instance containing the equally‐spaced instants produced by pandas.date_range, expressed in the requested scale.

Raises:
ValueError

If neither start nor end nor periods/n_points is provided, or if step conversion fails.

Examples

>>> # hourly UTC from 2025-01-01 00:00 to 2025-01-02 00:00
>>> Time.range(start='2025-01-01', end='2025-01-02', step='1H')
>>> # ten points between two Time objects, in TT
>>> t0 = Time('2025-01-01T00:00', scale='UTC')
>>> t1 = Time('2025-01-02T00:00', scale='UTC')
>>> Time.range(scale='TT', start=t0, end=t1, n_points=10)
Time.steps#

Time.steps: ndarray[double] Compute time intervals between consecutive entries, in seconds.

Returns:
intervalsndarray of float, shape (N-1,)

Array of time differences Δtᵢ = tᵢ₊₁ – tᵢ, expressed in seconds.

Time.to_astropy(self) aspy_Time#

Convert this Time to an Astropy Time object.

Returns:
astropy.time.Time

An Astropy Time instance with the same values, using the “datetime64” format and the current scale.

Time.to_pandas(self) pandas.DatetimeIndex#

Convert this Time to a pandas DatetimeIndex or Timestamp.

Returns:
pandas.DatetimeIndex or pandas.Timestamp

A pandas datetime object localized to UTC. If this Time has more than one entry, returns a DatetimeIndex; otherwise returns a single Timestamp.

classmethod Time.now(cls) Time#

Construct a Time for the current UTC instant.

Returns:
Time

A Time object representing pandas.Timestamp.utcnow() in UTC.

Time.ut1_utc#

Time.ut1_utc: ndarray[double] The difference UT1-UTC, a.k.a \(\Delta UT\) or \(\Delta UT1\) (in seconds)

Time.ut1_tai#

Time.ut1_tai: ndarray[double] The difference UT1-TAI (in seconds)

Time.tt_ut1#

Time.tt_ut1: ndarray[double] The difference TT-UT1, a.k.a \(\Delta T\) (in seconds)

Time.tai_utc#

Time.tai_utc: ndarray[double] The difference TAI-UTC, a.k.a \(\Delta AT\) (in seconds)