Linux "date" command ignores leap-seconds?
D. Hugh Redelmeier
hugh-pmF8o41NoarQT0dZR+AlfA at public.gmane.org
Wed Jan 16 19:59:08 UTC 2013
| From: Eric B <gyre-Ja3L+HSX0kI at public.gmane.org>
| Yes, unix timestamps do not account for leap seconds, BUT
| that is inconsistent with the 'man date' documentation.
On my Fedora 17 system, time(2) says
NOTES
POSIX.1 defines seconds since the Epoch as a value to be interpreted as
the number of seconds between a specified time and the Epoch, according
to a formula for conversion from UTC equivalent to conversion on the
naive basis that leap seconds are ignored and all years divisible by 4
are leap years. This value is not the same as the actual number of
seconds between the time and the Epoch, because of leap seconds and
because clocks are not required to be synchronised to a standard refer-
ence. The intention is that the interpretation of seconds since the
Epoch values be consistent; see POSIX.1 Annex B 2.2.2 for further
rationale.
That leap year rule is wrong since years divisible by 100 but not 400
are not leap years. We'll see in 2100 (if we make it past 2038).
Actually, if you look up POSIX.1 from 2004
<http://pubs.opengroup.org/onlinepubs/000095399/> and go to 4.14
"Seconds Since the Epoch", you will see that they do handle centuries
correctly.
One scary sentence:
How any changes to the value of seconds since the Epoch are made
to align to a desired relationship with the current actual time is
implementation-defined. As represented in seconds since the Epoch,
each and every day shall be accounted for by exactly 86400
seconds.
So there is no leeway to make some days a second longer.
Anyway, here is their formula:
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
I'd have written that with smaller, more understandable constants:
tm_sec + 60 * (tm_min + 60 * (tm_hour + 24 * (tm_yday
+ 365 * (tm_year-70)
+ (tm_year-69)/4
- (tm_year-1)/100
+ (tm_year+299)/400)))
tm_year is years since 1900. It would be better if it were
just "year". Then more constants would be understandable:
tm_sec + 60 * (tm_min + 60 * (tm_hour + 24 * (tm_yday
+ 365 * (tm_year-1970)
+ (tm_year-1969)/4
- (tm_year-1901)/100
+ (tm_year-1601)/400)))
Clearly all leap years before the Epoch don't count, but ones after do.
Years that are multiples of 4 are leap years (UNLESS they are multiples
of 100 (UNLESS they are multiples of 400)). A leap year delays the
start of subsequent years by one day.
1969 is the year after the last multiple of 4 before the epoch.
1901 is the year after the last multiple of 100 before the epoch.
1601 is the year after the last multiple of 400 before the epoch
--
The Toronto Linux Users Group. Meetings: http://gtalug.org/
TLUG requests: Linux topics, No HTML, wrap text below 80 columns
How to UNSUBSCRIBE: http://gtalug.org/wiki/Mailing_lists
More information about the Legacy
mailing list