NASA



Requirements for handling leap seconds in CDF

2011 May 26

Robert M. Candey robert.m.candey@ 1-301-286-6707

NASA Goddard Space Flight Center, Code 672, Greenbelt MD 20771 USA

1.0 Time in CDF

1.1 Problem

Current CDF_Epoch time scheme is nominally continuous Gregorian time from 0AD with no leap seconds or defined coordinate system. In practice, it generally holds UTC times, but leap seconds are overloaded onto the first second of the next day. Also mission data generally have ill-defined times, sometimes including leap seconds and sometimes only UTC at start of mission with no leap seconds afterwards. Science data should have well-defined times to enable more accurate cross-comparison between missions and as documentation for future archive use. The leap second issue does not generally affect data before 1972.

1.2 Current CDF times

The CDF project currently supports specialized time variables: CDF_EPOCH (8-byte float) and CDF_EPOCH16 (two 8-byte floats). CDF_EPOCH is milliseconds from 0AD (a leap year) in an undetermined coordinate system; and CDF_EPOCH16 is seconds from 0AD and picoseconds within that second. At present, the CDF library routines for converting between Epoch and YMD HMS is reversible in the sense that they will return the same HMS as was used on input, but don't allow entering an actual leap second. Simple subtraction of Epochs does not include leap seconds in between. Strictly speaking, CDF Epoch (as it stands) is time from 0AD with no leap seconds, but in practice time values are usually entered in UTC, whether they included leap seconds during the mission or not. Epoch assumes the Gregorian calendar leap year scheme into the past (even though they should probably be Julian days before 1582). Since Epoch conversion routines ignore leap seconds, a leap second and the first second of the next day are set to the same EPOCH value and converting back returns the first second of the next day. It also ignores the varying lengths of seconds in UTC from 1961 to 1972 (both UTC second longer than SI second and leaps added in sub-second units).

GPS, SOHO, THEMIS, C/NOFS and other missions don't add leap seconds, while WMAP, Wind, Geotail, Polar, TRACE, RXTE do. To further complicate things, missions update their spacecraft clocks over a period of time around the leap seconds, as much as days off, and some slew the spacecraft clock over time and some increment at once but not always on time. Missions carry time in CDFs in EPOCH/EPOCH16, ASCII variables as strings, ISTP-like PB5 values, or in double-precision variables for seconds since some base time (such as THEMIS Unix time). These various schemes greatly hinder cross-comparison of data with other missions and hinder use by general data analysis tools (CDAWeb, Autoplot, etc.), requiring custom software development and attendant errors.

1.3 CDF proposal for new time variable

CDF will add a new CDF data type, CDF_TIME_TT2000, defined as an 8-byte signed integer with a fixed Time_Base=J2000 (Julian date 2451545.0 TT or 2000 January 1, 12h TT), Resolution=nanoseconds, Time_Scale=Terrestrial Time (TT), Units=nanoseconds, Reference_Position=rotating Earth Geoid. Given a current list of leap seconds, conversion between TT and UTC is straightforward (TT = TAI + 32.184s; TT = UTC + deltaAT + 32.184s, where deltaAT is the sum of the leap seconds since 1960; for example, for 2009, deltaAT = 34s). Accurate conversions from other time scales may require that data providers use the JPL NAIF SPICE or similar library, but data users will easily be able to convert to UTC time. Use of an 8-byte integer provides time with nanosecond resolution for the next 280 years, so data providers will no longer need 16-byte CDF_EPOCH16 variables to carry their highest time resolution (and in half the storage space).

CDF_EPOCH/CDF_EPOCH16 and their conversion routines will continue to be supported (including for times outside the range of CDF_TIME_TT2000) and will have variable attributes for defining the Time_Scale, Reference_Position, Resolution, and Leap_Seconds_Included (as well as Epoch's fixed Time_Base=0AD and Units=milliseconds). These attributes may also be applied to other time variables such as THEMIS times and for returning to mission times (which may lack some leap seconds).

1.4 Variable attributes for time documentation (not needed for predefined CDF_TIME_TT2000)

Time_Base: fixed (0AD, 1900, 1970 (POSIX), J2000 (used by CDF_TIME_TT2000), 4714 BC (Julian)) or flexible (provider-defined)

Time_Scale: TT (same as TDT, used by CDF_TIME_TT2000), TAI (same as IAT, TT-32.184s), UTC (includes leap seconds), TDB (same as SPICE ET), EME1950 [default: UTC]

Reference_Position [optional]: Topocenter (local), Geocenter , rotating Earth geoid (used by CDF_TIME_TT2000)

Reference_Position is optional metadata to account for time variance with position in the gravity wells and with relative velocity. While we could use a combined TimeSystem attribute that defines mission-specific time scales where needed, such as UTC-at-STEREO-B, it's cleaner to keep them separate as Time_Scale=UTC and Reference_Position=STEREO-B.

Leap_Seconds_Included [required for UTC only]: comma-delimited list (within brackets) of leap seconds included in the form of a lists of ISO8601 times when each leap second was added, appended with the size of the leap second in ISO8601 relative time (+/- time, most commonly: "+1s") [default: standard list of leap seconds up to time of data]

Leap_Seconds_Included is needed to account for time scales that don't have all 34 (in 2009) leap seconds and for the clocks in various countries that started using leap seconds at different times. The full list is required to handle the equally or more common case where a time scale starts at a specific UTC but continues on without leap seconds in TAI mode; this is basically what missions that don't add leap seconds are doing.

$ cat tai-utc.dat | awk 'ORS="," { val = $7 - prev } {prev = $7} { print $1$2"01+" val "s" }'

Leap_Seconds_Included="1961JAN01+1.42282s,1961AUG01-0.05s,1962JAN01+0.47304s,1963NOV01+0.1s,1964JAN01+1.29427s,1964APR01+0.1s,1964SEP01+0.1s,1965JAN01+0.1s,1965MAR01+0.1s,1965JUL01+0.1s,1965SEP01+0.1s,1966JAN01+0.47304s,1968FEB01-0.1s,1972JAN01+5.78683s,1972JUL01+1s,1973JAN01+1s,1974JAN01+1s,1975JAN01+1s,1976JAN01+1s,1977JAN01+1s,1978JAN01+1s,1979JAN01+1s,1980JAN01+1s,1981JUL01+1s,1982JUL01+1s,1983JUL01+1s,1985JUL01+1s,1988JAN01+1s,1990JAN01+1s,1991JAN01+1s,1992JUL01+1s,1993JUL01+1s,1994JUL01+1s,1996JAN01+1s,1997JUL01+1s,1999JAN01+1s,2006JAN01+1s,2009JAN01+1s"

Units [optional]: SI measurement unit: s, ms, ns (10^-9 seconds for 8-byte CDF_TIME_TT2000), ps

Resolution [optional]: using ISO8601 relative time format, for example: 1s

Resolution provides the smallest change in time that is measured.

Absolute_Error [optional]: Absolute or systematic error in same units as Units attribute.

Relative_Error [optional]: Relative or random error in same units as Units attribute to specify the accuracy of the time stamps relative to each other. This is usually much smaller than Absolute_Error.

Time_Binning [optional]: relative position of time stamp to the data measurement bin, with 0.0 at beginning of time bin and 1.0 at end Default is 0.5 for the time at the center of the data measurement. Since clock readings are usually truncated, the real value may be closer to 0.0.

1.5 Difference between existing use of EPOCH and new CDF_TIME_TT2000

Use of CDF_TIME_TT2000 is substantially the same as for EPOCH. Data providers will add their time variables in SKTeditor or text skeleton file with the new variable type before creating the data CDFs. Data providers are responsible for accurately converting their data times to CDF_TIME_TT2000 time format, via routines such as the SPICE library or using the UTC-to-TT2000 conversion routines provided with the CDF library. The resulting 8-byte integers will be written to the CDFs with the same calls as for other variables. Data users will read the time variables as they do for other variables and then use the CDF library routines for conversion to UTC. The main change will be that the conversion routines will need an up-to-date list of leap seconds; scripts will be provided for updating the list included with the CDF software.

2.0 Software development

Add data type CDF_TIME_TT2000 read/write to CDF API and code; add routines for converting between TT2000 and UTC times (as strings and time parts); add interfaces for Matlab, IDL, Java and Perl; add to SKTeditor

2.1 CDF Internals

Pad values of -9223372036854775808 (0x8000000000000000) which corresponds to 1707-09-22T12:13:15.145224192; recommended FILLVAL is same.

Change User Guide section 2.5.4 to "Time Data Types" and add:

"CDF_TIME_TT2000 8-byte signed integer

The CDF_TIME_TT2000 data type is used to store date and time values as a signed integer number of nanoseconds in Terrestrial Time (TT) on the rotating Earth Geoid from J2000 (Julian date 2451545.0 TT or 2000 January 1, 12h TT). The standard format used to display a CDF_TIME_TT2000 value is yyyy-mm-ddThh:mm:ccccccc, with subseconds down to nanosecond resolution."

Add CDF_INT8 and CDF_TIME_TT2000 to "2.5.5 Equivalent Data Types"

Add CDF_TIME_TT2000 and EPOCH16 to other references of CDF_EPOCH throughout the document.

2.2 New software routines:

Besides adding the new data types, CDF_INT8 and CDF_TIME_TT2000, the main changes will be to create new versions of the various time-handling routines, and add conversions between CDF_EPOCH* and CDF_TIME variables. The UTC-related routines require an up-to-date list of leap seconds. This list will be read in on the first call to the routine and stored in a common block or global variable for performance reasons. The read routine could check for an updated list at the standard URLs and compare it to the cached list, although this is best done periodically through a separate script or cron job. An environment variable will be used to point to the list when in a non-standard place and can be used to over-ride the standard list if desired (perhaps to handle conversion back to mission time that only used a subset of leap seconds).

generic time conversion routines for C, Fortran, IDL, Perl, Java, Python, Matlab

2.2.1 CDF_time_to_UTC_parts

CDF_time_to_UTC_parts returns arrays of time parts in UTC from an input array of CDF_TIME_TT2000 values. Fortran and C version has scalar parameters only (no arrays).

CDF_time_to_UTC_parts(cdf_time_var, year, [month, day, hour, minute, second, millisecond, microsecond, nanosecond])

with input parameter time as CDF_int8[ ] and all output parameters in CDF_REAL4[ ] (should there be a version for CDF_REAL8?).

The various output parameters are almost all optional with the last parameter receiving the remainder as fractional units [Mike is this doable?]. No easy way to get day-of-year rather than day-of-month? Fractional month is not allowed as ill-defined. Output parameters (when provided) have the usual constraints (year[1707-2292], month[1-12], day[1-31 or 1-366], hour[0-23]. minute[0-59], second[0-60], millisecond[0-999], microsecond[0-999], nanosecond[0-999]).

2.2.2 CDF_time_from_UTC_parts

CDF_time_from_UTC_parts returns an array of CDF_TIME_TT2000 values computed from input arrays of time parts in UTC. Fortran and C version has scalar parameters only (no arrays).

CDF_int8[ ] CDF_time_from_UTC_parts(year, [month, day, hour, minute, second, millisecond, microsecond, nanosecond])

with input parameters all in CDF_REAL4[ ] (should there be a version for CDF_REAL8?) as fractional units (for instance year can include fractional years as well). Fractional month is not allowed as ill-defined.

The various input parameters are almost all optional and accumulate appropriately. In particular, subsecond variables (millisecond, microsecond, nanosecond) are optional and usually second with fractional seconds is used if the variable has enough resolution. Basically the input values would sum up into nanoseconds (adding leap seconds as needed) after multiplying by the appropriate constants. For the special case of month=0, day becomes day-of-year rather than day-of-month.

Example calls:

time = CDF_time_from_UTC_parts(1970., 1., 1., 0., 0., seconds_input) # allows seconds from Unix beginning

time = CDF_time_from_UTC_parts(2000., 0., modified_julianday-0.5) # use modified Julian day times

We could have a CDF_time_from_UTC_parts_strict routine that has usual constraints (year[1707-2292], month[1-12], day[1-31 or 1-366], hour[0-23]. minute[0-59], second[0-60], millisecond[0-999], microsecond[0-999], nanosecond[0-999]), possibly all in integers; but probably better to leave to users to check unless this is too hard to code.

2.2.3 CDF_time_to_UTC_string

CDF_time_to_UTC_string returns arrays of time strings in UTC from an input array of CDF_TIME_TT2000 values. Fortran and C version has scalar parameters only (no arrays).

CDF_char[ ] CDF_time_to_UTC_string(cdf_time_var, [time_format, time_resolution])

Same as CDF_time_to_UTC_parts but returning time as a string in a standard format or user specified time_format (if we use a standard library). If provided, Time_resolution provides how much resolution to compute, specified using ISO8601 relative time format (for example: 1s). If an illegal field is detected, the value returned will be ILLEGAL_EPOCH_VALUE.

time_format values (default is 3)

0 DD-Mon-YYYY hh:mm:ccccccc

1 YYYYMMDD.ttttttt

2 YYYYMMDDhhmmss

3 YYYY-MM-DDThh:mm:cccccccZ (The characters T and Z are the CDF_EPOCH type 3 place holders)

where:

DD the day of the month (1-31)

Mon the abbreviated month name: (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, or Dec)

MM the month number (1-12)

YYYY the year (A.D.)

hh the hour (0-23)

mm the minute (0-59)

ss the second (0-59)

cccccccccc fractional seconds

The SPICE library handles more time string formats .

2.2.4 CDF_time_from_UTC_string

CDF_time_from_UTC_string returns arrays of CDF_TIME_TT2000 values computed from arrays of time strings in UTC. Fortran and C version has scalar parameters only (no arrays).

CDF_int8[ ] CDF_time_from_UTC_string(time_string, [time_format])

Same as CDF_time_from_UTC_parts but computing from time strings in a standard format or user specified time_format (if we use a standard library). If an illegal field is detected, the value returned will be ILLEGAL_EPOCH_VALUE. time_format is same as for CDF_time_to_UTC_string.

2.2.5 CDF_time_from_UTC_EPOCH

CDF_time_from_UTC_EPOCH returns arrays of CDF_TIME_TT2000 values computed from arrays of CDF_EPOCH values in UTC. Fortran and C version has scalar parameters only (no arrays).

CDF_int8[ ] CDF_time_from_UTC_EPOCH(CDF_EPOCH[ ] epoch_time)

Same as CDF_time_from_UTC_parts but computing from CDF_EPOCH values, assumed to be in UTC.

perhaps provide similar routine for CDF_EPOCH16:

CDF_int8[ ] CDF_time_from_UTC_EPOCH16(CDF_EPOCH16[2, ] epoch_time)

2.2.6 CDF_time_to_UTC_EPOCH

CDF_time_to_UTC_EPOCH returns arrays of CDF_EPOCH values in UTC computed from arrays of CDF_TIME_TT2000 values. Fortran and C version has scalar parameters only (no arrays).

CDF_EPOCH[ ] CDF_time_to_UTC_EPOCH(CDF_int8[ ] cdf_time_var)

Same as CDF_time_to_UTC_parts but computing to CDF_EPOCH values in UTC.

perhaps provide similar routine for CDF_EPOCH16

2.2.6 CDF_time_compare

Compare two arrays of CDF_TIME_TT2000 values and return array of integers, where 1 if the value of time1 is greater (a later date and time) than time2, 0 if same, and -1 if time1 is less than time2.

CDF_int2[ ] Result = CDF_time_compare(time1, time2)

2.2.7 CDF_time_difference

Return difference in time between two input arrays of CDF_TIME_TT2000 values, time1 - time2 in nanoseconds.

CDF_int8[ ] Result = CDF_time_difference(time1, time2)

Perhaps add optional resolution parameter to specify rounding to seconds, milliseconds or microseconds.

2.2.8 CDF_TIME object functions (draft ideas)

Ideas for a generic CDF time object scheme that perhaps could subsume EPOCH and EPOCH16 also, and perhaps use SPICE library to handle many time schemes.

new (arraySize): create new CDF_TIME object with arraySize values (default to 1)

read (fileID, [varName]): read CDF_TIME variable, varName (default to "time") from CDF file opened with fileID

write (fileID, [varName]): write CDF_TIME variable, varName (default to "time") from CDF file opened with fileID

compareTo(cdf_time2): return array of -1 (less), 0 (same), +1 (more) values for self object compared to cdf_time2 object

difference(cdf_time2, [/seconds, /milliseconds, /microseconds, /nanoseconds]): return array of (self - cdf_time2) in seconds, milliseconds, microseconds, nanoseconds (default)

toString([timeFormat, Time_Scale=Time_Scale, Reference_Position=Reference_Position, Leap_Seconds_Included=Leap_Seconds_Included, Resolution=Resolution, Units=Units, Time_Base=Time_Base]): convert times to string of timeFormat (defaults to ISO8601 form) in Time_Scale (defaults to UTC) from Time_Base with Leap_Seconds_Included (defaults to standard list from NIST) with Resolution (defaults to "+1s")

fromString: same as above in reverse.

toBreakdown(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond, Time_Scale=Time_Scale, Reference_Position=Reference_Position, Leap_Seconds_Included=Leap_Seconds_Included, Resolution=Resolution, Units=Units, Time_Base=Time_Base): same as toString but returns arrays of time parts. Last given part contains fractional values for remaining Resolution.

fromBreakdown: same as toBreakdown in reverse; parts can be zero or large and time will sum appropriately.

toTime(Time_Scale=Time_Scale, Reference_Position=Reference_Position, Leap_Seconds_Included=Leap_Seconds_Included, Resolution=Resolution, Units=Units, Time_Base=Time_Base): returns one-dimensional array of times in Time_Scale (useful for J2000, POSIX time, etc.)

fromTime: same as toTime in reverse

2.3 Software development notes

block older CDF software with new magic number if needed, else CDF reading routines will not recognize the new data type

encode checks second=60 against the leap seconds list

how to cache leap second list (common block)

how to update leap second list regularly (scripts, check via URL when connected to network, perhaps warn user to run small utility to update)

2.4 Development Schedule

*************************************************************************

3.0 Background:

There are more ways of measuring time (calendars and time scales) than you might think. Basically UT1 follows the Earth's rotation and UTC stays within 0.9 seconds using leap seconds, and TAI is atomic time with no leap seconds. Countries use various versions of UTC and GMT as their time basis . The US proposes to stop adding leap seconds . There are many time systems in use and it's not clear what exact time system is used on each mission. GPS, SOHO, THEMIS, C/NOFS and other missions don't add leap seconds, while WMAP, Wind, Geotail, Polar, TRACE, RXTE do. Some software packages do and some don't. Strictly speaking, CDF Epoch (as it stands) has no leap seconds from 0 AD, but in practice time values were basically entered in UTC, whether they included leap seconds during the mission or not.

Mostly, people assume they know what is meant by a specific time measurement, when in fact time scales and units have varied greatly over the years and even now still come in many flavors. Heliophysics missions are similarly inconsistent, with some using the spacecraft counter, others use a running clock, and other upload corrections to time including leap seconds. To further complicate things, missions update their spacecraft clocks over a period of time around the leap seconds, as much as days off, and some slew the spacecraft clock over time and some increment at once but not always on time. These complications are too confusing to document in a standard way inside the CDFs but should be covered in mission documentation. For better accuracy, the Leap_Seconds_Included list could have the times when each leap second was fully added to the spacecraft clock.

Because missions use different time bases, with and without leap seconds, we could either document what time systems are used where possible (and enable entering leap seconds) (with their attendant complexities), or develop a fixed time system suitable for archiving and easy reading, as proposed here.

3.1 Time scales:

At least with most metric units, there is a standard specification for each, but not for time. Even ignoring many local times and summer time shifts, time scales include:

Universal Time (UT): based on the rotation of the Earth on its axis (mean solar day)

Ephemeris Time (ET): based on the revolution of the Earth in its orbit around the Sun

Atomic Time (AT): based on the quantum mechanics of the atom

UT1: true measure of the Earth's rotation, corrected for polar motion and used in celestial navigation

UT2: UT1 corrected for the seasonal variation due to irregularities in the Earth's rotation

International Atomic Time (TAI): uniform time scale maintained by the BIPM

Coordinated Universal Time (UTC): atomic time scale at rate of TAI but kept within 0.9 s of UT1 by leap seconds as decided by International Earth Rotation Service (IERS) (current civil time)

Terrestrial Dynamical Time (TDT) or Terrestrial Time (TT): like ET with origin on the Earth geoid, (TAI + 32.184 s)

GPS Time (GPST): origin at midnight of 1980 January 5/6 so TAI is constantly ahead of GPS Time by 19 s, and UTC currently behind by 15s

Temps International (TI): proposed new time system without leap seconds

EME1950 - seconds since 1950 Jan 1 00:00:00 in Earth Mean Equator.

J2000 - seconds since 2000 Jan 1 12:00:00 in Earth Mean Equator

Julian Date (JD) - days and fractions since noon January 1, 4714 BC (Julian calendar)

POSIX or "Unix time" - seconds since UTC January 1, 1970, not counting leap seconds. The signed 32bit implementation will overflow on 2038-01-19T3:14:08Z. Unix time often counts then uncounts the leap seconds or slews the computer clock for a bit.

CDF_EPOCH: time from 01-Jan-0000 00:00:00.000, no leap seconds, so 19s behind GPS, 34s behind TAI, 12s? behind Tplot epoch

Many more Time Scales at .

Barycentric Coordinate Time (TCB) at the geocenter, remains close to Terrestrial Time (TT) for an extended time span

Barycentric Dynamical Time (TDB): origin at center of the solar system (often used for ephemeris)

TDB be defined as the following linear transformation of TCB: TDB = TCB − LB x (JDTCB − T0) x 86400 + TDB0, where T0 = 2443144.5003725, and LB = 1.550519768x10−8 and TDB0 = − 6.55 x 10−5 s are defining constants.

From Paul Sheer:

NTP time is a 32-bit logical second count since 1900 (with a 32-bit subsecond part) with 86400 logical seconds per day. On the leap second, NTP time subtracts by 1 full second - i.e. it has a step jump of 1 full second *back* in time. NTP time tracks GPS time less the number of leap seconds.

Unix time in practice is the realization in practice of Posix time on Unix (and Unix-like and other OS) computers. It has 86400 logical seconds per day. It tracks NTP time with one exception: on the leap second it *stops* (usually) for one full second *instead* *of* going backward by one full second. It is a 32/64-bit (signed) value of logical seconds since 1970, or exactly NTP time minus 2208988800. Unix time is the time most of the world's computers display. Unix time (as ASCII) is the time most of the world *thinks* is legal time. They are mostly right about this, except near the leap second. "time_t is one second per SI second, steady state." Leap seconds perturb this steady-state in any number of implemetnation dependent ways: (1) Time stops for a second; (2) The last second of the day repeats; (3) The first second of the day repeats; (4) Time slews from N seconds before midnight to N seconds after midnight; (5) Nothing happens, until NTP notices the phase error and steers it out; (6) Nothing happens, and time is wrong.

Posix time is just a definition of the relationship between days and logical seconds: i.e. there are 86400 of them in a day and the first day is 1970-01-01. Posix time is a 32/64-bit (signed) logical second value.

UTC is the human readable (ASCII) realization of time with proper inclusion of the leap second so that some minutes have 61 seconds, for example 2012-12-31 23:59:60. Except near the leap second, Unix time, NTP time, and UTC can be converted between each other precisely and losslessly (reversibly). Unix time (as displayed in ASCII) and UTC differ only in that Unix time pauses on the leap second for a full extra second, whereas UTC counts up to 60. They otherwise tick over identically. Almost no computers on earth display proper UTC across the leap second, but few lay people know this (or care).

Olson right time is the computer-internal realization of UTC, *even* *though* *no* *standard* *defines* *this* (I think). Olson right time is one of two time scales the Olson library supports: right time and regular unix (aka "posix") time. Olson right time is an SI (caesium) second count since 1970 as a 32/64-bit value. Olson right time can *always* be converted to UTC and back again *losslessly* even on a leap second. Olson right time cannot be used on a Unix system because: 1) Olson right time has days that are sometimes 86401 seconds, 2) Olson right time values are offset with Unix time values (currently) by 24 seconds, 3) OS+NTP support does not generate Olson right time time stamps, and 4) there is no such thing as a perfect *future* Olson right time because one doesn't know if a leap second will be inserted that will offset it by say 1 second. Olson right time is GPS time plus 9.

GPS time is Olson right time less 9, and TAI less 19. GPS time has an extra field for the current leap second count since 1980 (when there were only 9 leap seconds) and a field for future leap seconds. GPS time accumulates seconds since 1980 in the form of truncated weeks (week mod 1024) and time of week.

UTC-SLS is Unix time without a 1 second pause. Instead, time adjusts with a well-defined gradient over a course of time near the leap second.

In addition, time varies with gravity and speed relativisticly, and so properly should include documenting location and velocity, but the relativistic effects are small for most current missions.

3.2 Current CDF time handling

The CDF project supports specialized time variables: CDF_EPOCH (8-byte float) and CDF_EPOCH16 (two 8-byte floats). CDF_EPOCH is milliseconds from 0AD (a leap year) in an undetermined coordinate system and CDF_EPOCH16 is seconds from 0AD and picoseconds within that second. The following routines are available for conversion:

computeEPOCH[16] calculates a CDF_EPOCH[16] value given the time individual components

EPOCH[16]breakdown decomposes a CDF_EPOCH[16] value into the time individual components

encodeEPOCH[16]* encodes a CDF_EPOCH[16] value into various date/time character string formats

parseEPOCH[16]* parses various date/time character formats and returns a CDF_EPOCH value

CDF routines in IDL:

CDF_EPOCH[16] procedure computes or breaks down CDF_EPOCH[16] values

CDF_ENCODE_EPOCH[16] function encodes a CDF_EPOCH[16] variable into a string

CDF_EPOCH_COMPARE function compares two epoch (date and time) values

CDF_EPOCH_DIFF function compares two epoch (date and time) values and returns the difference in milliseconds (default) or microseconds

CDF_PARSE_EPOCH[16] function parses a properly-formatted input string into a double-precision value

Matlab

?

3.3 Time used by Missions

WMAP onboard UTC clock, leap second field updated as single stored cmd, clock error and drift adjusted weekly (+- 15ms)

Wind (+- 10 ms), leap second adjusted in ten 100ms steps over 2 hours to minimize impact on attitude sensors and stored commands

SOHO no leap seconds, uses TAI (actually 6-byte onboard clock)

TRACE leap second adjustment

RXTE leap second

ACE no onboard UTC clock, just counter, leap seconds added in gnd processing

FDF uses Timing coefficients file; used predicted leap seconds from 1998-2002 so off by 1-2 sec

Geotail divides data files at leap seconds. That is, one file ends at XX:59:60, and the other file starts at XX:00:00

THEMIS going with non-leap seconds across the board

C/NOFS no leap seconds

STEREO uses UTC

/* CCSDS epoch is 1 Jan 1958 */

/* PB5J epoch is 24 May 1968 */

/* time_t epoch is 1 Jan 1970 */

/* HST epoch is 25 Apr 1990 */

/* TRMM epoch is 1 Jan 1994 */

/* XTE epoch is 1 Jan 1994 (for B2 patch) */

/* TRACE epoch is 24 May 1968 */

/* SWAS epoch is 24 May 1968 */

Two-Line orbital Elements (TLE) use time since the epoch (TSE) of the file, so orbit propagation software should add any leap second that occurred since the epoch of the TLE file. Sardi's models and SSCweb internally have no leap seconds; FDF presumably accounts for leap seconds. STK uses leap seconds.

Space Physics Coordinate Transformations: transforming from inertial coordinates (as used for spacecraft orbits) to coordinate systems spinning with the Earth requires UTI as a measure of the spin phase of the Earth. Leap seconds are used to keep UTC within 0.9 seconds of UT1 (a spin phase error of less than 6.5e-5 radians). Do coordinate transformation software automatically assume leap seconds? If so, dropping leap seconds (as recently proposed to the ITU) will require obtaining the difference between true UT1 and whatever time system is used. Mike Hapgood on coordinate transforms from

3.4 Time Software

Perhaps the best source code for time conversions is in the JPL SPICE system

(also nice string conversion routine)

command line tool

NOVAS library is unencumbered

IAU Standards of Fundamental Astronomy (SOFA)

3.5 Lists of leap seconds

A historical tabulation of leap-seconds:  

(no longer available?)

3.6 References

proposed POSIX time API

NVO Time coordinate metadata

IERS Conventions

Standish, E. M., "Time scales in the JPL and CfA ephemerides", Astronomy and Astrophysics, v.336, p.381-384 (1998)

Fukushima, T., "Time ephemeris", Astronomy and Astrophysics, vol. 294, no. 3, p. 895-906, 02/1995

IERS Conventions

USNO

Space-Time Coordinate Metadata for the Virtual Observatory

IAU Time Commission 31

"The Debate over UTC and Leap Seconds"

R A Nelson , D D McCarthy , S Malys , J Levine , B Guinot , H F Fliegel , R L Beard and T R Bartholomew, "The leap second: its history and possible future", Metrologia Vol. 38, #6, p. 509 (2001), doi:10.1088/0026-1394/38/6/6

Mailing list on dropping leap seconds:

NASA has proposed a fall back recommendation making GPS time (with no leap seconds) a standard interval time scale for precision timekeeping projects, while leaving UTC alone:

A history of the proposal to eliminate leap-seconds oriented against the proposal:

3.7 Orbit Data Messages CCSDS 502.0-B-2 ANNEX A Nov 2009

VALUES FOR TIME_SYSTEM AND REFERENCE_FRAME (NORMATIVE)

The values in this annex represent the set of acceptable values for the TIME_SYSTEM and REFERENCE_FRAME keywords in the OPM, OMM, and OEM. (For details and description of these time systems, see reference [G1].) If exchange partners wish to use different settings, the settings should be documented in the ICD.

A1 TIME_SYSTEM METADATA KEYWORD

If MET or MRT is chosen as the TIME_SYSTEM, then the epoch of either the start of the mission for MRT, or of the event for MET, should either be given in a comment in the message or provided in an ICD. The time system for the start of the mission or the event should also be provided in the comment or the ICD. If these values are used for the TIME_SYSTEM, then the times given in the file denote a duration from the mission start or event. However, for clarity, an ICD should be used to fully specify the interpretation of the times if these values are to be used. The time format should only utilize three digit days from the MET or MRT epoch, not months and days of the months.

Time System Value

GMST Greenwich Mean Sidereal Time

GPS Global Positioning System

MET Mission Elapsed Time (note)

MRT Mission Relative Time (note)

SCLK Spacecraft Clock (receiver) (requires rules for interpretation in ICD)

TAI International Atomic Time

TCB Barycentric Coordinate Time

TDB Barycentric Dynamical Time

TCG Geocentric Coordinate Time

TT Terrestrial Time

UT1 Universal Time

UTC Coordinated Universal Time

TDB or TT can be approximated by TDB=UTC+32.184s+; TT and TDB differ by ................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download