[LEAPSECS] Time math libraries, UTC to TAI

Brooks Harris brooks at edlmax.com
Sat Dec 31 17:39:31 EST 2016


On 2016-12-31 01:21 AM, Zefram wrote:
> Brooks Harris wrote:
>> There is a hole in the data of these tables; Rec 460 tells us the origin of
>> TAI is "1 January 1958" but the first TAI-UTC value listed in the tables is
>> in 1961 - what happened between 1958 and 1961?
> You've previously shown some confusion along these lines, and I think
> the origin of it is becoming clearer.
I was confused for a long time, that's for sure. I'm not alone. That's 
where I hope, plead, for an authoritative due-process consolidation of 
the UTC specs and local time to emerge from some SDO that would guide 
detailed understanding of the topics. This might help dispel confusion 
and prevent future implementers from suffering the brain damage caused 
by studying and comparing every timekeeping document known to man in 
search of a consistent and common method, which still seems elusive.
> You've erred by trying to treat
> TAI and UTC as a closely-tied pair, in particular trying to apply the
> same threshold dates to them.
I'm not exactly sure what you mean by "threshold dates". This seems like 
a new term, but I get your drift. (Wait, is "drift" the same as "smear"? 
:-) )

I think many on LEAPSECS are pursuing different objectives so it's first 
necessary to state what we are trying to accomplish,.

I came into this from the point of view of television and broadcast 
timekeeping. Here, we deal with the (pesky!) NTSC video rate of 
30000/1001 frames per second. That "1001" denominator causes all sorts 
of confusion and implementation difficulty. The media industry relies on 
"SMPTE time code" (SMPTE ST 12) for timekeeping and media labeling 
purposes, and it historically is limited to a "24 hour working period" 
span - it had no accurately defined relationship to UTC or local time. 
But it works deterministically for synchronization and labeling media 
units and has "glued" the entire industry together for many decades.

As SMPTE turned to defining a fixed-epoch timescale for media 
timekeeping and selected IEEE 1588/PTP as the basis for network-based 
media synchronization we are confronted with reconciling the many media 
components and frequencies with accurate time-of-day. The users expect, 
demand, that "time-of-day" mean *local* time-of-day. Humans expect the 
familiar YMDhms representation of local time, or "wall clock".

Meantime, many SMPTE (and other) 1588/PTP implementations will probably 
derive their master PTP clock from GPS. There are millions of PC's 
involved with every OS known to man, so POSIX time and Windows time 
comes into play. And if these don't match NTP reasonably well something 
will obviously be amiss.

So, in my view, this means developing a set of documents that encompass 
all these timescales in such a way as to enable deterministic 
interoperability. We are concerned with keeping accurate date and time 
at and after 1972-01-01 00:00:10 (TAI) = 1972-01-01T00:00:00 (UTC) (call 
this "UTC1972" for short); accurate representation before this instant 
is explicitly out of scope. However, because the NTP, TAI, and POSIX 
origins lie before UTC1972 we must define how these are to be normalized 
to UTC1972.

There are many timescales for many purposes. 1588/PTP cannot represent 
date and time prior to 1970 TAI. GPS cannot represent date and time 
prior to 1980-01-06T00:00:00 (UTC). The mission I'm interested in is 
practical timekeeping after UTC1972 while maintaing reverse 
compatibility to imporat existing timescales.

I applaud the efforts by others to attempt to find consensus of date and 
time prior to 1972. That will be valuable to many disciplines concerned 
with history and its terribly interesting. But it is outside the scope 
of my, and many other's, primary objective of finding a common and 
deterministic formula for describing date and time in the here and now.


> One would think that it would be easy to
> grasp that different time scales each have their own epoch.  It sounds
> like you've gone into this with a preconceived notion that the entirety of
> modern horology sprang into existence at a single instant.  You're having
> difficulty in abandoning this preconception in the face of evidence.
UTC, with an integral second offset to TAI, *did* spring into existence 
at a single instant; 1972-01-01T00:00:00Z (UTC). I'd call that time 
point the beginning of the modern timekeeping era, the "mother of all 
epochs". Any system that claims to be date and time accurate must 
normalize to this internationally agreed reference point.

The "rubber band" development era, from roughly 1960 (preliminary work 
on atomic clocks was underway) until 1971, when the development had led 
to the convergence of the atomic clock frequency and an *integral* 
second offset to the *new* UTC. As of that moment the historical 
non-integer atomic time-to-solar time values were rendered obsolete. 
What justification is there to cling to those historical values for 
practical timekeeping purposes? Its a controversial quagmire. Its more 
useful, and convenient, to just forget it.

You're having difficulty in abandoning this preconception in the face of 
evidence. :-)

>> In the end the only sensible thing to do is ignore these obsolete facts and
>> establish a proleptic integral-second timescale. That's exactly what NTP
>> does,
> No, that's not a particularly sensible thing to do, and it's not what
> NTP does.  NTP is silent on how UTC behaved prior to the existence
> of NTP
NTP is not silent on this, see more below...

> , and that *is* a sensible approach for any system that's only
> concerned with present times.
Right.
> The same applies to the use of PTP: one
> need not take any position on how UTC or even TAI behaved prior to the
> 21st century.  The PTP epoch only need be defined sufficiently to give
> meaning to current PTP timestamps.
Right.
>> 1588 states "7.2.2 Epoch - The PTP epoch is 1 January 1970 00:00:00 TAI,
>> which is 31 December 1969 23:59:51.999918 UTC.". (This is consistent with
>> Steve's statement above - "At 1970-01-01 the difference TAI - UTC(BIH) was
>> 8.000082 SI seconds."). However, this seems in conflict with Annex B, Table
>> B.1 - Relationships between timescales, one entry of which says "NTP Seconds
>> = PTP Seconds + 2 208 988 800 - currentUtcOffset".
> There is no conflict.  The table entry is perfectly correct, over the
> range of times for which all the terms are defined.  If one engages in
> the dubious exercise of applying NTP and PTP concepts to a time as early
> as 1969, even then the equation is correct.  At the instant of the PTP
> epoch, we have
>
> 	NTP Seconds ~= 2208988791.99918
> 	PTP Seconds = 0
> 	currentUtcOffset ~= 8.000082
>
> all of which is consistent with the equation.  The only part of this
> that is at all problematic is currentUtcOffset being non-integral, which
> cannot be represented in the PTP protocol.
Indeed, that's the rub. It can't be represented in the PTP protocol and 
its not computationally very convenient. Also, by the reckoning in RFC 
5905, NTP, RFC 5905 Figure 4: Interesting Historic NTP Dates, NTP 
Seconds would be 2,208,988,790. See below.
> That means that it would be
> difficult to actually use PTP in 1969, but there are a couple of other
> difficulties there that overshadow this one.  Note that, with respect to
> such historical application of the concepts, PTP's Annex B explicitly
> says "Prior to 1 January 1972, corrections to the offset between UTC
> and TAI were made in fractions of a second.".
That is true, but its a statement of historical significance only.
>
> If the fractionality were to somehow cause a real problem -- and I'm
> failing to see the use case for which this would occur with respect
> to PTP --
In the media business it causes precision implementation problems. The 
terribly inconvenient NTSC frame rate of 30000/1001 is a repeating 
decimal number (30000/1001 = 29.(970029) ). There are many other media 
frequencies and components to consider. If the SMPTE/1588/PTP epoch is 
not treated as integral seconds before UTC1972 things get unmanageably 
and unnecessarily complicated. That's the point of the note in ST 2059 
"Note: The SMPTE Epoch is 63072010 seconds before 1972-01-01T00:00:00Z 
(UTC)"
> one could use a proleptic extension of leap-seconds UTC,
> such as Tony Finch's pUTC.  This would round off the above numbers.
> pUTC would give, for the PTP epoch:
>
> 	NTP Seconds = 2208988792
> 	PTP Seconds = 0
> 	currentUtcOffset = 8
>
> This is no longer consistent with real UTC history, but it does permit
> current PTP-related code to think about 1969.  Of course, there's no
> reason to stop there: if one wants PTP code to think about 1969, then
> why not 1929 too?  There's nothing special about the PTP epoch from this
> point of view.
>
> Returning for a moment to the subject of your (Brooks's) psychology, you
> grant epochs a huge unjustified significance.  You seem to think, despite
> any actual application requirements, that it is essential for modern
> code in any of these systems to be able to operate in the region where
> time is represented by a scalar value of zero (i.e., at the protocol's
> nominal epoch).  By implication, you seem to also think that this code
> does not need to be able to operate on any earlier time.
Well, yes, that's right - accurate timekeeping prior to UTC1972 is not 
an objective, but justifying the NTP, PTP, and POSIX origins for 
purposes of normalizing them to UTC1972 for convenience of computation is.

> It is quite
> bizarre to use the nominal epoch as this threshold of applicability.
> You need to use different thresholds for different purposes, choosing
> each threshold appropriately based on the uses to which it will be put.
>
>>                If date-time before 1972 UTC is treated as integral seconds
>> the same way NTP and POSIX define their origins the PTP epoch is 1970-01-01
>> 00:00:00 (TAI) = 1969-12-31T23:59:50 (UTC).
> No, that doesn't follow.  If you apply a fictitious UTC which is
> always an integral number of seconds offset from TAI, then, within this
> counterfactual universe, it necessarily follows that in 1969 the TAI-UTC
> offset was integral.  It does not follow that it was exactly 10 s.
> One has a fairly free choice in what offset to apply to any particular
> pre-1972 time, but some choices are clearly better than others.  10 s
> is a poor choice for the second half of 1969, because it means that the
> UT1-UTC difference is well beyond its modern bounds, despite it being
> very easy to keep it in bounds.  8 s is the only option for December
> 1969 that keeps UT1-UTC within the modern bound.
>
> Also, NTP and POSIX don't imply this kind of pre-1972 UTC.  They're both
> silent on the issue.
POSIX is intentionally vague on the issue, but NTP is not:

 From RFC 5905, https://tools.ietf.org/html/rfc5905

    In the date and timestamp formats, the prime epoch, or base date of
    era 0, is 0 h 1 January 1900 UTC, when all bits are zero.  It should
    be noted that strictly speaking, UTC did not exist prior to 1 January
    1972, but it is convenient to assume it has existed for all eternity,
    even if all knowledge of historic leap seconds has been lost. Dates
    are relative to the prime epoch...

RFC 5905 Figure 4: Interesting Historic NTP Dates shows

+-------------+------------+-----+---------------+------------------+
    | Date        | MJD        | NTP | NTP Timestamp | Epoch            |
    |             |            | Era | Era Offset |                  |
+-------------+------------+-----+---------------+------------------+
    | 1 Jan -4712 | -2,400,001 | -49 | 1,795,583,104 | 1st day Julian   |
    | 1 Jan -1    | -679,306   | -14 | 139,775,744   | 2 BCE            |
    | 1 Jan 0     | -678,491   | -14 | 171,311,744   | 1 BCE            |
    | 1 Jan 1     | -678,575   | -14 | 202,939,144   | 1 CE             |
    | 4 Oct 1582  | -100,851   | -3  | 2,873,647,488 | Last day Julian  |
    | 15 Oct 1582 | -100,840   | -3  | 2,874,597,888 | First day        |
    |             |            |     |               | Gregorian        |
    | 31 Dec 1899 | 15019      | -1  | 4,294,880,896 | Last day NTP Era |
    |             |            |     |               | -1               |
    | 1 Jan 1900  | 15020      | 0   | 0             | First day NTP    |
    |             |            |     |               | Era 0            |
    | 1 Jan 1970  | 40,587     | 0   | 2,208,988,800 | First day UNIX   |
    | 1 Jan 1972  | 41,317     | 0   | 2,272,060,800 | First day UTC    |
    | 31 Dec 1999 | 51,543     | 0   | 3,155,587,200 | Last day 20th    |
    |             |            |     |               | Century          |
    | 8 Feb 2036  | 64,731     | 1   | 63,104        | First day NTP    |
    |             |            |     |               | Era 1            |
+-------------+------------+-----+---------------+------------------+

The "First day UTC" entry shows an integral number of seconds from 
"First day NTP" to "First day UTC"; 2,272,060,800 s.

The prime epoch is called "0 h 1 January 1900 UTC". The UTC calibration 
point is 1972-01-01T00:00:00Z (UTC).

(I'd like to side-step naming that span as a timescale because 
discussion always devolves into arguments about what to call various 
timescales prior to 1972. A stickler could argue that NTP erred in 
calling the prime epoch UTC in the first place. Same with POSIX "the 
Epoch". Maybe the closest might be "Gregorian before UTC1972". I'll use 
that in this discussion)

2272060800 / 86400 = 26297 exactly. That's 26297 86400-second-days.

If you consider that span, or interval, in isolation as a timescale, any 
time point along it can by represented in YMDhms form by applying the 
(pure) Gregorian calendar counting method. Those YMDhms representations 
cannot be considered date-time accurate with respect to UTC and it is 
explicitly stated to be used for *convenience*; "UTC did not exist prior 
to 1 January 1972, but it is convenient to assume it has existed for all 
eternity..."

Note that the 86400-second-day character of this span implies that a 
TAI-UTC of 10 s was in effect at "0 h 1 January 1900 UTC" if A) an 
abstract proleptic TAI timescale is constructed for convenience, and B) 
the span is treated as pure Gregorian calendar. TAI-UTC = 10 s as of 
1972-01-01 00:00:10 (TAI) = 1972-01-01T00:00:00 (UTC). On a proleptic 
TAI, and a "proleptic UTC (prior to 1972 UTC as Gregorian calendar)" 
you'd have the prime epoch at 1900-01-01 00:00:10 (proleptic TAI) = 
1900-01-01 00:00:00 ("Gregorian before UTC1972").

Note too the "First day UNIX" entry in Table 4. It is also an integral 
second offset from "First day NTP". Is this the POSIX "the Epoch"? I'd 
say strictly, no, because RFC 5905 has no jurisdiction in the POSIX 
realm. But every indication is the POSIX "the Epoch" evolved from "UNIX 
time" before it. So, it may be reasonable to say POSIX the Epoch = 
1970-01-01 00:00:00 (Gregorian before UTC1972), and its convenient to 
treat it that way. Some systems do.


>> The SMPTE Epoch shall be 1970-01-01T00:00:00TAI, which is the same as the PTP
>> Epoch specified in IEEE
>> Standard 1588-2008.
>>
>> Note: The SMPTE Epoch is 63072010 seconds before 1972-01-01T00:00:00Z (UTC).
> This too does not have the implication that you state.  It specifies
> an epoch in three ways, all of which agree with each other, and which
> do not require one to take any position on pre-1972 UTC.  The only use
> of UTC here is to specify a time that uncontroversially corresponds to
> 1972-01-01 00:00:10 TAI.  The SMPTE Epoch that the passage describes lies
> exactly 63072010 TAI seconds before that instant.  (It's not 63072010
> UTC seconds, and the note would be clearer if it specified "TAI seconds"
> rather than just "seconds".)
The word "seconds" is taken to mean SI seconds, which, of course, are 
coincident with TAI seconds. The note is referring  to a seconds 
duration, and I think calling it "TAI seconds" would be confusing 
because it implies some numbering of those seconds, which there is not - 
its an integral seconds duration.
>>                                                                    the SMPTE
>> "note" says, and the intention is it be, 1969-12-31T23:59:50 (UTC).
> No, it doesn't say that.  It doesn't say anything about the UTC
> representation of the SMPTE Epoch.
True.
> Hypothetically, if it did state
> "1969-12-31 23:59:50 UTC" then that would be a problem, because it would
> be inconsistent with the other ways in which the SMPTE Epoch is specified.
The inconsistency resides in the 1588/PTP specification. That's why the 
note is there, to make it clear the SMPTE Epoch is treated an integral 
number of seconds before UTC1972. And note, as I understand it from 
discussion, most PTP implementations take this same approach because a 
fractional second starting point is not convenient or helpful to 
practical timekeeping after UTC1972. Essentially, the second part of the 
1588/PTP epoch sentence, "... which is 31 December 1969 23:59:51.999918 
UTC." and most of Annex B, except Table B.1, are just ignored.
>
> In any proleptic UTC-with-leap-seconds that covers that period,
> those 63072010 seconds *would* be 63072010 pseudo-UTC seconds, due
> to pseudo-UTC seconds being identical to TAI seconds by stipulation.
> It would be this many pseudo-UTC seconds regardless of the leap schedule
> of the pseudo-UTC.  Even in this situation, the passage still doesn't
> say anything about the (pseudo-)UTC representation of the SMPTE Epoch.
> It would be a second-aligned pseudo-UTC time, of course, but not
> necessarily 23:59:50, and indeed for it to be that would imply poor
> tracking of UT1 by the pseudo-UTC.
Tracking of UT1 before UTC1972 is not part of this mission. UTC 
approximately tracks UT1 after UTC1972, that's the heavy lifting the 
BIPM and IERS do for us. This mission about is tracking UTC after 
UTC1972 and defining local time based on it.

POSIX gmtime() converts time_t to "broken down time". Typical 
implementations include code to use the 1970 the epoch.

gmtime(63072000) =  1972-01-01 00:00:00
gmtime(0) =  1970-01-01 00:00:00
gmtime(-10) =  FAILS

If you tweak gmtime() to perform the Gregorian algorithm using the PTP 
epoch, call it gmtimePTP(), you get

gmtimePTP(63072010) =  1972-01-01 00:00:00
gmtimePTP(10) =  1970-01-01 00:00:00
gmtimePTP(0) = 1969-12-31 23:59:50

Its much more convenient and useful that way.

Have a great Leap Second and a Happy New Year!

-Brooks


>
> -zefram
> _______________________________________________
> LEAPSECS mailing list
> LEAPSECS at leapsecond.com
> https://pairlist6.pair.net/mailman/listinfo/leapsecs
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://pairlist6.pair.net/pipermail/leapsecs/attachments/20161231/adea0815/attachment-0001.html>


More information about the LEAPSECS mailing list