[tz] zoneinfo vs zoneinfo-leaps
John Haxby
john.haxby at oracle.com
Tue Nov 17 15:58:51 UTC 2015
On 16/11/15 22:17, Guy Harris wrote:
> On Nov 16, 2015, at 2:07 PM, John Haxby <john.haxby at oracle.com> wrote:
>
>> > Also Posix specifically says that there are 86400 seconds in a day, every day, without exception. It allows for the time 23:59:60
> It does?
>
> If there are 86400 seconds in every day, then every day begins at 00:00:00 and ends at 23:59:59, which is followed by 00:00:00 of the next day. No room for 23:59:60 there.
>
It does, and you can have 23:59:60.
This, obliquely, says that the number of seconds in a day is 86400:
http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_15
and this says that there can be 61 seconds in a minute:
http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/time.h.html
Which is nice. The upshot is that 1435708799 is ambiguous: you can't
tell whether it was 23:59:59 or 23:59:60 (it was both).
On Linux, adjtimex(2) returns TIME_OOP if you're in the middle of a
leapsecond so that you can tell the difference between the first and
second times through 1435708799:
#include <time.h>
#include <sys/timex.h>
struct tm *gmtimestamp_r(struct tm *tm, long *ns)
{
struct timespec ts1, ts2;
clock_gettime(CLOCK_REALTIME, &ts1);
if (ts1.tv_sec % 86400 == 86399) {
struct timex tx = { .modes = 0 };
int status = adjtimex(&tx);
clock_gettime(CLOCK_REALTIME, &ts2);
if (ns)
*ns = ts2.tv_nsec;
gmtime_r(&ts2.tv_sec, tm);
if (status == TIME_OOP && ts1.tv_sec == ts2.tv_sec)
/* we're in a leap second */
tm->tm_sec++;
} else {
if (ns)
*ns = ts1.tv_sec;
gmtime_r(&ts1.tv_sec, tm);
}
return tm;
}
Other platforms that allow ntp to tell the kernel a leap second is on
its way provide similar system calls. Posix doesn't mention adjtimex(2)
or indeed anything that will tell you if you're in a leap second.
You can have *endless* fun with leap seconds :) Well, OK, you can bore
people to death.
jch
More information about the tz
mailing list