On 16/11/15 22:17, Guy Harris wrote:
On Nov 16, 2015, at 2:07 PM, John Haxby <john.haxby@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_... 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