time - Time conversion, manipulation and implementation of Ticktock class

Time conversion, manipulation and implementation of Ticktock class


The handling of time, in particular the conversions between representations, can be more complicated than it seems on the surface. This can result in some surprising behavior, particularly when requiring second-level accuracy and converting between time systems outside of the period 1972 to present. It is strongly recommended to use TAI if transferring times between SpacePy and other libraries. TAI has a consistent, unambiguous definition and no discontinuities.

Some time systems (e.g. the UTC representation via datetime) cannot represent times during a leapsecond. SpacePy represents all these times as the latest representable time in the day, e.g.:

>>> spacepy.time.Ticktock('2008-12-31T23:59:60').UTC[0]
datetime.datetime(2008, 12, 31, 23, 59, 59, 999999)

Conversions between continuous time representations (e.g. TAI), leap second aware representations (e.g. ISO timestrings), and those that ignore leap seconds (e.g. UTC datetime, Unix time) are well-defined between the introduction of the leap second system to UTC in 1972 and the present. For systems that cannot represent leap seconds, the leap second moment is considered not to exist. For example, from 23:59:59 on 2008-12-31 to 00:00:00 on 2009-01-01 is two seconds, but only represents a one-second increment in Unix time. Details are also discussed in the individual time representations.

UTC times more than six months in the future are not well-defined, since the sechedule of leap second insertion is not known in advance. SpacePy performs conversions assuming there are no leapseconds after those which have been announced by IERS.

Between 1960 and 1972, UTC was defined by means of fractional leap seconds and a varying-length second. SpacePy treats UTC time in this period similar to after 1972, with a consistent second the same length of the SI second. It applies leap seconds wherever there is an entry in the USNO record of TAI-UTC, rounding fractional total leap second countss to the integer (0.5 rounds up). This results in the application of six leap seconds at the beginning of 1972. The discrepancy with other means of calculating TAI-UTC may be as much as five seconds at the end of this period.

Before 1960, UTC is not defined. SpacePy assumes days of constant length 86400 seconds, equal to the SI second. This is almost guaranteed to be wrong; for times well out of the space era, it is strongly recommended to work consistently in either a continuous time system (e.g. TAI) or a day-based system (e.g. JD).

SpacePy assumes dates including and after 1582-10-15 to be in the Gregorian calendar and dates including and before 1582-10-04 to be Julian. 10-05 through 10-14 do not exist. This change is ignored for continuously-running non leap second aware timebases: CDF and RDT.

See the Ticktock documentation and its various get functions for more details on the exact definitions of time systems used by SpacePy.


>>> import spacepy.time as spt
>>> import datetime as dt

Day of year calculations

>>> dts = spt.doy2date([2002]*4, range(186,190), dtobj=True)
>>> dts
[datetime.datetime(2002, 7, 5, 0, 0),
datetime.datetime(2002, 7, 6, 0, 0),
datetime.datetime(2002, 7, 7, 0, 0),
datetime.datetime(2002, 7, 8, 0, 0)]
>>> dts = spt.Ticktock(dts,'UTC')
>>> dts.DOY
array([ 186.,  187.,  188.,  189.])

Ticktock object creation

>>> isodates = ['2009-12-01T12:00:00', '2009-12-04T00:00:00', '2009-12-06T12:00:00']
>>> dts = spt.Ticktock(isodates, 'ISO')


>>> dtdates = [dt.datetime(2009,12,1,12), dt.datetime(2009,12,4), dt.datetime(2009,12,6,12)]
>>> dts = spt.Ticktock(dtdates, 'UTC')

ISO time formatting

>>> dts = spt.tickrange('2009-12-01T12:00:00','2009-12-06T12:00:00',2.5)


>>> dts = spt.tickrange(dt.datetime(2009,12,1,12),dt.datetime(2009,12,6,12),     dt.timedelta(days=2, hours=12))
>>> dts
Ticktock( ['2009-12-01T12:00:00', '2009-12-04T00:00:00', '2009-12-06T12:00:00'] ), dtype=ISO
>>> dts.isoformat()
Current ISO output format is %Y-%m-%dT%H:%M:%S
Options are: [('seconds', '%Y-%m-%dT%H:%M:%S'), ('microseconds', '%Y-%m-%dT%H:%M:%S.%f')]
>>> dts.isoformat('microseconds')
>>> dts.ISO

Time manipulation

>>> new_dts = dts + tdelt
>>> new_dts.UTC
[datetime.datetime(2009, 12, 2, 18, 0),
 datetime.datetime(2009, 12, 5, 6, 0),
 datetime.datetime(2009, 12, 7, 18, 0)]

Other time formats

>>> dts.RDT  # Gregorian ordinal time
array([ 733742.5,  733745. ,  733747.5])
>>> dts.GPS # GPS time
array([  9.43704015e+08,   9.43920015e+08,   9.44136015e+08])
>>> dts.JD # Julian day
array([ 2455167. ,  2455169.5,  2455172. ])

And so on.

Authors: Steve Morley, Josef Koller, Brian Larsen, Jon Niehof Institution: Los Alamos National Laboratory Contact: smorley@lanl.gov,

Copyright 2010 Los Alamos National Security, LLC.


Ticktock(data, dtype)

Ticktock class holding various time coordinate systems (TAI, UTC, ISO, JD, MJD, UNX, RDT, CDF, DOY, eDOY, APT)


dtstr2iso(dtstr[, fmt])

Convert a datetime string to a standard format

doy2date(year, doy[, dtobj, flAns])

convert integer day-of-year doy into a month and day after http://pleac.sourceforge.net/pleac_python/datesandtimes.html

leapyear(year[, numdays])

return an array of boolean leap year, a lot faster than the mod method that is normally seen

randomDate(dt1, dt2[, N, tzinfo, sorted])

Return a (or many) random datetimes between two given dates

sec2hms(sec[, rounding, days, dtobj])

Convert seconds of day to hours, minutes, seconds

tickrange(start, end, deltadays[, dtype])

return a Ticktock range given the start, end, and delta