[tz] Adapting localtime.c

John Haxby john.haxby at oracle.com
Sun Oct 9 10:19:08 UTC 2016


> On 9 Oct 2016, at 02:52, Robert Elz <kre at munnari.OZ.AU> wrote:
> 
>    Date:        Sat, 8 Oct 2016 21:59:44 +0100
>    From:        John Haxby <john.haxby at oracle.com>
>    Message-ID:  <E732F782-B470-4FF9-8754-CA018858AF94 at oracle.com>
> 
>  | The epoch is approximately=94 midnight at the beginning of 1970.
> 
> No, it is exactly the beginning of 1970 (UTC).   The issue is that the
> "seconds" that are counted are not international standard seconds, but
> posix seconds, which are defined to be 1/86400 of the length of the day
> in which they occur.   That means that posix seconds can be slightly
> (very slightly) longer (or in principal, shorter) than IS seconds.
> 
> If you're trying to measure precise time intervals, posix seconds are
> useless (though they're fine if all you care about is the nearest 1/10
> of a second or so) but for working with calendars, they're ideal, as there's
> no need to keep a table of when leap seconds occur (which, as they're
> unpredictable, is the only way to deal with them.)

http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap04.html#tag_04_14

> 4.14 Seconds Since the Epoch
> 
> A value that approximates the number of seconds that have elapsed since the Epoch.

It goes on to say that “the relationship between the actual time of day and the current value for seconds since the Epoch is unspecified” and “each and every day since the Epoch shall be accounted for by exactly 86400 seconds”.     To my eyes, it’s quite obviously trying to avoid mentioning leap seconds and the fact that some days actually have a different number of seconds.   The trouble is, once you introduce leap seconds and a defined conversion from seconds since the Epoch to struct tm then you introduce a whole lot of pain doing arithmetic with struct tm.

A second really is a second though, there’s nothing about approximating the length of a second.   Interestingly, some people use gettimeofday(2) as an interval timer and can’t cope with it going backwards when there’s a leap second so they trade accuracy for uptime :) and use ntpd -x even though they should be using a monotonic clock (time since an unspecified epoch, often boot time) which doesn’t go backwards.   Also anyone who stores a timestamp as seconds since the epoch is in trouble because there are values that represent two distinct times, ie 23:59:59 and 23:59:60 UTC when there’s a leap second inserted.   They still do it, of course, and sooner or later the trading systems people are going to start complaining loudly that This Will Not Do™.   (I’ve mentioned before that ntp_gettime, which isn’t posix, allows for discovering whether or not you’re in a leap second so you can convert clock_gettime(CLOCK_REALTIME) to 23:59:60 for the affected one billion nanoseconds.)

Time is so much fun :)

jch





More information about the tz mailing list