[LEAPSECS] Toasting Unix timestamp 1234567890
zefram at fysh.org
Sat Feb 14 16:45:28 EST 2009
Magnus Danielson wrote:
>leap in TAI-UTC offset as measured in TAI seconds needs to be converted
>into UTC seconds. However... is it the UTC seconds of the previous era
>or the new era? It's a singularity so you can't use the slope of the
This is an issue that I had to resolve to write Time::UTC. From examining
tai-utc.dat and pushing the numbers around, I came to the conclusion
that the model of UTC is consistently that:
* leaps occur by adding or removing (fractional) seconds at the end of
a UTC day
* the duration of a leap is always a round (or, at least, terminating
decimal) number of TAI seconds
* the duration of a UTC second is likewise always a terminating decimal
number of TAI seconds
* discontinuities in TAI-UTC offsets (which result from leaps) occur
precisely at the boundary between UTC days
* frequency shifts in UTC also occur precisely at the boundary between
To get 86400.107758 UTC seconds in 1971-12-31, you would have to
suppose that the frequency change occurred at 23:59:60.000, and that
UTC then ticked at the same frequency as TAI for 0.107758 seconds until
1972-01-01T00:00:00. I don't see anything indicating that the frequency
shift and discontinuity of TAI-UTC (the end of the leap) occurred at
different instants. tai-utc.dat shows the two as one event.
I suppose my comments about the TAI-UTC difference deserve some
explanation. utc-tai.dat handles dates in terms of JD and (equivalently)
MJD, but describes the calculation of the relationship between TAI and UTC
in terms of a difference in seconds. In a strict 86400-seconds-per-day
timescale, such as TAI, MJD and seconds are trivially interconvertible,
but MJD doesn't quite work right with UTC.
I determined that the MJDs given in tai-utc.dat actually refer to
UTC, not TAI. Firstly, the boundary dates given are exact midnights
according to the MJD, and as we know leaps occur at midnight UTC.
Secondly, calculating this way shows that at the frequency shifts in
the rubber-seconds era, other than the final shift at the end of 1971,
there was no simultaneous leap. 1961-12-31, for example, had exactly
86400 UTC seconds.
To determine the MJD of a UTC time, we can divide up the UTC timestamp
into a date and time of day. These can be expressed as an integral
MJDN (Modified Julian Day Number) and a fractional number of seconds
since midnight (ssm). Then MJD = MJDN + ssm/86400. This is, in fact,
the same way that POSIX time is specified to behave. MJD[UTC] thus has
funny behaviour at leaps. During a positive leap, ssm>=86400, so MJD[UTC]
appears to be in the following day. MJD[UTC] then has a discontinuity
at the start of the following day.
I then interpret the "TAI-UTC" difference, which is given in seconds,
as being 86400 s * (MJD[TAI] - MJD[UTC]). Putting all of this together,
this results in UTC seconds on a day with a leap (such as 1964-03-31)
having the (expected) same length as the UTC seconds of the preceding day.
Any other way of calculating MJD[UTC] would break that.
Sorry if the above is difficult to follow. After all this time,
having found this to be the only consistent interpretation, I'm having
difficulty wrapping my head round other interpretations to explain why
they don't work.
More information about the LEAPSECS