[LEAPSECS] BBC radio Crowd Science
Brooks Harris
brooks at edlmax.com
Sat Feb 4 05:58:44 EST 2017
On 2017-02-03 11:24 PM, Tom Van Baak wrote:
> Hi Warner,
>
>> But consider TAI and UTC when they were equal, for the sake of
>> argument. I know they never were, but if we look at what the first one
>> would look like:
> That's a nice, clear example. Thanks.
>
>> 23:59:58 23:59:58 0
>> 23:59:59 23:59:59 0
>> 00:00:00 23:59:60 1
>> (since how can it be 0 if they are different?)
> Ah, the offset can be 0 *because* they are different. In fact, the offset *must* be 0. You see, there's no need for *both* the :60 *and* the 1 offset at the same time. Each of them on their own are capable of indicating a one second difference from normal:
> - A :60 by its unique value tells you there is a now an offset of +1 second in the time scale.
> - And dTAI being 1 tells you there is now an offset of +1 in the time scale.
>
> You don't need *both* of them. When you're in a leap second, the extra-normal value of the :SS itself tells you an offset. And when you're not in a leap second that information carries over to dTAI to tell you the offset. Their *sum* at any instant is the difference between the time scales.
>
>> So either there's some weird math that lets one subtract two numbers
>> that are different and get 0 as the answer, or the delta has to change
>> at the start.
>>
>> It's understanding what the weird math is that I'm having trouble with
>> for people that say it is after the leap second that the delta
>> changes.
> Well, yes, it is sort of weird math. It's operations on time stamps, not integer counts of seconds. Look at it this way:
> - In decimal arithmetic you have 10 symbols, so you carry when you pass 9. If you wrap from 9 to 0 and do not carry you've lost count.
> - In seconds arithmetic you have 60 symbols, so you carry when you pass 59. If you wrap from 59 to 00 and do not carry you've lost count.
>
> Further, UTC is not just regular time stamps. Leap seconds are clever. They invent a new symbol, called "60". This symbol, by its very existence, holds a new count without actually carrying. It allows you to postpone the carry until you are ready to wrap to 00. Once you wrap, though, something else needs to keep track of that extra count or you'll lose count. And that something is dTAI.
>
> So this means the time scales physically diverge at the beginning of the negative or positive leap second, but the integer value of dTAI doesn't increment until you're finished with the time stamp(s) that have excess-60 in them; that is, at the moment you roll over to :00.
>
> Remember, the pseudo math you're trying to solve is something like this:
> TAI = UTC + (TAI-UTC)
>
> It's not being done with integers, in decimal or in hex; it's not even being done in mixed-radix 24:60:60 format. Instead it's being done with an optional extra symbol. So the "equation" is always true. It's just that once in a while, during a positive leap second, the value of the "UTC" in the equation (via use of an extra symbol) is 1 greater than usual. To keep the equation true, the value of "TAI-UTC" remains the same while this happens. It's only when the time stamp rolls over to :00, that the extra 1 moves over from the "UTC" part to the "TAI-UTC" part of the equation.
>
> /tvb
This is where I've called it an "encoding". Its not just math. UTC has
this extra, irregularly introduced, encoding factor.
In SMTPE timecode, the hh:mm:ss:videoframes (hmsf) representation is an
encoding of the number of video frames since a zero origin. The origin,
and the hmsf values have nothing to do with the calendar or time-of-day;
they are just incrementing counts since an abstract "zero".
If the video frame rate is 25/1 (the PAL (Phase Alternate Line)
standard, used in Europe and elsewhere), there are 25 frames per *true
SI second*. In a frames count value encoded as hmsf the hh:mm:ss behaves
as you'd expect, incrementing the seconds every 25 frames, the minutes
every 60 seconds, etc. The hmsf is an encoding of the number of frames,
for example 01:00:00:00 is 90,000 frames (3600 seconds * 25
frames-per-second = 90,000 frames). Its a straight forward encoding
using the "24-hour timekeeping system" as ISO 8601 calls it (ss = s, mm
= 60s, hr = 60mm, day = 24hr).
00:59:59:23 = 89998 frames
00:59:59:24 = 89999 frames
01:00:00:00 = 90000 frames
01:00:00:01 = 90001 frames
The hmsf representation is a deterministic encoding of 90,000 1/25
frames-per-second frames. And the hh:mm:ss portions will increment in
true time, so the running time is indicated by the hmsf values which is
very familiar and handy for humans to read and use.
But with the NTSC (National Television Standards Committee) standard
used in the US, Japan, and elsewhere, things are a bit more tricky. The
NTSC frame rate is 30000/1001. This is approximately ~29.97 frames per
true SI second. That 1001 denominator is *evil* - the frame rate is
actually a repeating decimal number; 29.(970029). This has to be treated
as 30 frames per *nominal* second because the 30 frames occur not in one
SI second, but in 1.01 SI seconds; 30 / (30000/1001) = 1.001.
When an NTSC frame count is encoded as hmsf (with no compensation, as
will be described shortly) 01:00:00:00 = 108000 frames. This is a
deterministic encoding of the frames value in hmsf form.
00:59:59:28 = 107998 frames
00:59:59:29 = 107999 frames
01:00:00:00 = 108000 frames
01:00:00:01 = 108001 frames
This uncompensated encoding is called "non-drop-frame count mode".
However, the hh:mm:ss portion is *not* an encoding of SI seconds, as it
was in the 1/25 frame rate example above. Here, the "seconds" value does
not represent SI seconds but 1.001 SI seconds, and so the "minutes" are
60 * 1.001 and "hours" are 3600 * 1.001.
01:00:00:00 = 108000 frames, yes, but 108000 frames pass in 3603.6 SI
seconds (108000 / (30000/1001) = 3603.6), so the hh:mm:ss portions do
not represent true running time. This is *not* familiar and handy for
humans concerned with real time, as broadcasters are. Missing the air
time of a commercial during the Super Bowl by 3.6 seconds could cost the
network $millions!.
To compensate for this deceptive hmsf running time SMPTE timecode has a
"count mode" called "drop-frame", where two frame labels are "dropped",
or omitted. each "minute" (they aren't really minutes!) except each
tenth "minute".
First minute:
00:00:59:28 = 1798 frames
00:00:59:29 = 1799 frames
00:01:00:00 << omitted
00:01:00:01 << omitted
00:01:00:02 = 1800 frames
00:01:00:03 = 1801 frames
The hour rollover is a tenth "minute":
00:59:59:28 = 107890 frames
00:59:59:29 = 107891 frames
01:00:00:00 = 107892 frames << retained
01:00:00:01 = 107893 frames << retained
01:00:00:02 = 107894 frames
01:00:00:03 = 107895 frames
With that, the hh:mm:ss portions run very nearly at real-time. Its not
exact; there are approximately 2.5 frames left over at the end of 24
hours. But its close enough for broadcast purposes.
Now the point is the hmsf representation is an *encoding* of the frame
count. To do this encoding, that is, to convert from a frame count to
hmsf, or decode it, you need *metadata*. You need to know at least the
"count modulus" (number of frames-per-*nominal* second) and the "count
mode" (non-drop frame or drop-frame). To convert to true SI seconds
running time you also need the rate (1/25 or 30000/1001 in these examples).
The hmsf representation are only labels. They appear to be
mathematically consistent, but they are not, actually, at least not in
all cases. They are *encodings*. This can be misleading and you've got
to keep it in mind as an everyday user and as a developer. Its easy to
lose track of that because its so natural to to interpret the hmsf as a
"time", but its not, exactly. Its only a label. I repeat this mantra to
myself a lot - its only a label, its only a label...
Now return to TAI, UTC, and YMDhms representations.
First of all, our underlying algorithm is Gregorian (uncompensated for
Leap Seconds). Gregorian is an encoding of a date and time-of-day. The
date can be treated as a day-number, such as MJD; 1972-01-01T00:00:00
(UTC) = 41317 MJD. The date and time-of-day can be treated as
seconds-since-some epoch, such as TAI1958; 1972-01-01T00:00:00 (UTC) =
441763210 TAI. This can be encoded or decoded with no additional
metadata since all the factors are known.
You can implement Gregorian various ways. There are at least two well
known methods I'm aware of. I consider Gregorian trickier than the SMPTE
timecode manipulations I'm familiar with, what with its leap year
look-up. You can do the SMPTE calculations many of ways, including
manipulating the ascii values of a character representation of hmsf, but
it doesn't have anything quite like the Gregorian leap years.
But here comes Leap Seconds, irregularly and unpredictably introduced
into the YMDhms encoding. As Tom points out YYYY-MM-DD 23:59:60 can be
seen as a symbol marking the irregularly introduced Leap Second. They
might have labeled it 24:00:00 I guess, but they didn't. SMPTE timecode
has nothing like this irregular factor.
To encode seconds-since-some epoch as YMDhms(UTC) you need metadata. If
you're needing to represent the entire UTC timescale from UTC1972 you
need a complete Leap Second table. It you're calculating on the fly from
some time-link protocol you need at least the current, instantaneous,
TAI-UTC value and some way to identify the Leap Second, such as a "61"
flag. How these parameters are presented and updated are critical.
YMDhms(UTC ) is an encoding and its not just math. Its only a label. Its
not like some extra second materialized somehow when the Leap Second
occurs; where would it come from? Its only a label. This mantra applies
to local time and Daylight Savings YMDhms too. When a DST onset occurs,
like YMD 01:59:59 to YMD 03:00:00, its not like some extra hour
materialized or the location moved east 15 degrees. Its only a label,
its only a label....
-Brooks
More information about the LEAPSECS
mailing list