# [LEAPSECS] How good could civil timekeeping be?

Poul-Henning Kamp phk at phk.freebsd.dk
Thu Feb 14 16:53:37 EST 2008

In message <20080214210754.GA19375 at ucolick.org>, Steve Allen writes:

>There is a distinction. POSIX zoneinfo and its equivalents in other

>precison+civil time systems already have the mechanisms to let the

>distinction be clear. They can handle both a monotonic interval and a

>conversion to and from various epochs that corresponds to externally

>mandated standards.

This is not true.

This is the point where the POSIX people shot us in the feet by
ignoring leap-seconds.

The time_t type, contains the number of SI seconds since 1970-01-01
00:00:00 UTC *ignoring all leapseconds*.

This means that you can find the preceeding UTC midnight from
any time_t value by subtracting its modules of 86400:

> date +%s
1203025212 <--- time_t integer
> date -r 1203025212
Thu Feb 14 21:40:12 UTC 2008 <--- corresponding UTC time
> expr 1203025212 % 86400
78012 <--- Modulus (24*60*60)
> expr 1203025212 - 78012
1202947200 <--- time_t of preceeding midnight
> date -r 1202947200
Thu Feb 14 00:00:00 UTC 2008 <--- As UTC time

If time_t had correctly counted leapseconds, that would have been
23.mumle seconds off (leapseconds + rate and phase adjustments in
1970 and 1971).

This deficient definition means that you cannot correctly calculate
the number of SI seconds between two time_t's if they span a
leap-second, unless you have an external table of leapseconds to
reference.

And down at a hairsbreadth, you cannot by looking at a time_t value,
tell the leap second from the second right before it. (In some
cases it's the second after, but that's clearly a bug since the
leap second is the last second in the preceeding 24 hour UTC period.)

What zoneinfo brings to the table, is the information to convert
from a time_t to civil time and vice versa, all over the world
thoughtout time.

But even the zoneinfo leapsecond table can not solve the basic
problem telling the two identical time_t values apart.

This is of course analogous to the problem when sommertime ends and
people don't qualify the timestamp properly. Because the time_t
is in "almost UTC", this problem does not exist for time_t -> human
conversions but only for human->time_t conversions.

But because time_t is not qualified some way to mark leap seconds,
they suffer the problem on both directions.

There is far too much code and data out there to even contemplate
changing the definition of time_t.

It would also be a stupid thing to do from a QA point of view,
because it would not be readily appearant if the code was using
the old time_t or the new time_t definition.

So if leapeconds survive, we somehow have to force a new time typedef
and representation through POSIX, and get operating systems to
implement it.

If we just drop leapseconds, time_t is suddenly correct and
all the computer software and data files need no attention.

Unfortunately, it also means that we either sanction POSIX stupidity
or acknowledge their superior farsightedness, neither of which
is particularly satisfying to anybody.

--
Poul-Henning Kamp | UNIX since Zilog Zeus 3.20
phk at FreeBSD.ORG | TCP/IP since RFC 956
FreeBSD committer | BSD since 4.3-tahoe
Never attribute to malice what can adequately be explained by incompetence.