[LEAPSECS] leapseconds, converting between GPS time (week, second) and UTC

Warner Losh imp at bsdimp.com
Wed Jan 16 01:36:57 EST 2019


On Tue, Jan 15, 2019 at 10:09 PM Gary E. Miller <gem at rellim.com> wrote:

> Yo Warner!
>
> On Tue, 15 Jan 2019 17:45:32 -0700
> Warner Losh <imp at bsdimp.com> wrote:
>
> > > > Except that's not a leap second. struct tm doesn't do leap seconds
> > > > really. It kinda sorta does, but it kinda sorts doesn't.
> > >
> > > Well, it does in a modern Linux kernel.  Otherwise NTPD would fail
> > > on the leap second, and that only happens every year so.  :-)
> > >
> >
> > You are wrong. The kernel doesn't use struct tm.
>
> I never said the kernel uses struct tm.  I said you can query the kernel
> for
> the time in a struct tm.
>

What system call is that? A quick grep didn't turn anything up for me. All
the calls I'm aware of are library calls that get the system time and then
break it up.


> > The kernel does this
> > by ticking either in TAI or by incrementing a TAI offset. ntpd uses a
> > different interface that exposes these things to it so it can
> > broadcast the leap second indicators correctly.
>
> Yup.
>
> > > > First, when you convert back and forth to time_t, you lose leap
> > > > second information. It's impossible to convert back and forth
> > > > from at least the UTC time zone. There's some 'right' time zones,
> > > > but they aren't strictly speaking POSIX compliant because it uses
> > > > the wrong math. Non-conforming, but damned useful and not wrong.
> > >
> > > Which is why you can't use time_t in UTC,  but time_t in TAI
> > > can work, as well as struct tm, usually.  Lot's of latent bugs...
> > >
> >
> > No. time_t is not TAI or GPS. It is UTC. Adjusted UTC.
>
> No, time_t is just a way to count seconds.  See man difftime() for a
> use of time_t that is unrelated to any particular epoch.
>

This is the biggest mistake people make with POSIX time_t. It's not just a
way to count seconds. It is the funky seconds since 1970 thing. By
definition.

difftime takes two time_t's and returns a double that's the difference
between them. This is only a time_t when time_t is defined to be a double
(which is allowed, but apart from IBM, nobody has done that), otherwise it
is not. Typically, time_t is some int type, so difftime isn't a good
example here. Also, the open group standard is silent about what it's
supposed to do across a leap second, but since it operates on time_t, it's
unclear if a time_t of 12307679999 and 1230768002 should be 3 or 4 since
those two times straddle 2009 December 31, 23h 59m 60s. I've seen spirited
debate on both sides of that issue.

> It is the
> > number of SI seconds since 1970, minus all the positive leap seconds,
> > plus all the negative ones.
>
> Ciration please?  I already cited the Linux doc that says otherwise.
>

The Linux doc does not define the standard. The POSIX doc does (from the
Open Group 2017 edition):

3.150 Epoch

The time zero hours, zero minutes, zero seconds, on January 1, 1970
Coordinated Universal Time (UTC).
4.16 Seconds Since the Epoch

A value that approximates the number of seconds that have elapsed since the
Epoch. A Coordinated Universal Time name (specified in terms of seconds
(tm_sec), minutes (tm_min), hours (tm_hour), days since January 1 of the
year (tm_yday), and calendar year minus 1900 (tm_year)) is related to a
time represented as seconds since the Epoch, according to the expression
below.

If the year is <1970 or the value is negative, the relationship is
undefined. If the year is >=1970 and the value is non-negative, the value
is related to a Coordinated Universal Time name according to the C-language
expression, where tm_sec, tm_min, tm_hour, tm_yday, and tm_year are all
integer types:

tm_sec + tm_min*60 + tm_hour*3600 + tm_yday*86400 +
    (tm_year-70)*31536000 + ((tm_year-69)/4)*86400 -
    ((tm_year-1)/100)*86400 + ((tm_year+299)/400)*86400

which is equivalent to what I said based on how leap seconds work.

I've done a lot with POSIX time_t and what is and isn't stated in the
standard.  Linux may implement something that's not strictly POSIX
compliant, but the root of the problem with time_t is POSIX defines it very
particularly and when people deviate from the standard, or make their own
up when the standard is silent, they do so is somewhat divergent ways
(which is part of the problem as well as leap seconds not being defined in
time_t as there's no way to represent them uniquely in a time_t, despite
them existing in the non-uniform radix UTC notation).



> > > If you squint at it, GPS time (gps weeks, time of week) is just
> > > another notation very similar to time.  And we know that works.
> > >
> >
> > GPS time has no leap seconds. It's a monotonic count since 1980.
>
> Correct.
>
> > > Since future leap seconds are unknown, and unknowable, there is no
> > > possible valid way to do this on the time scale of years.
> > >
> >
> > Correct. This is the fundamental flaw of UTC.
>
> Or a flaw of the universe.  For some reason the earth refuses to rotate
> uniformly.
>

It's a fundamental flaw of UTC. There are other ways to implement something
akin to UTC that implements some form of mean solar time that's not an
observational calendar. We do that for leap days. We have a simple rule
that works for hundreds of years, and we don't worry that we can be as much
as 2 days off since on the average we're correct. UTC chose the DUT1 < 1s
rule instead of a rule that would insert things[*] on a longer term
schedule that would still keep the average the same. UTC isn't some magical
thing: it's a horrible kludge that the people who made it were too ashamed
of to talk openly about it for a long time.

Warner

[*] and yes, I'm aware that no simple rule is possible for hundreds of
years, but you could schedule them out a decade and still be on the average
correct, but violate the DUT1 rule.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://pairlist6.pair.net/pipermail/leapsecs/attachments/20190115/cfb6e713/attachment.html>


More information about the LEAPSECS mailing list