mktime

  • Thread starter Anders Wegge Keller
  • Start date
E

Eric Sosman

Eric Sosman said:
[...]
I remember seeing the [0..61] range for tm_sec long ago, and
perhaps it still persists in some non-C documents. Even in the
original 1989 ANSI C Standard, though, the range was [0..60] in
keeping with the fact that leap seconds are added (or removed)
one at a time, never two at once.

The 1990 ISO C standard specifies a range of [0, 61] for tm_sec:

int tm_sec; /* seconds after the minute -- [0, 61] */

with a footnote:

The range [0,61] for tm_sec allows for as many as two leap seconds.

C99 changes the range to [0, 60] and changes the footnote to:

The range [0, 60] for tm_sec allows for a positive leap second.

There's no mention of the change in the C99 rationale.

[...]

Are you *sure* that the 1989 ANSI standard specifies [0, 60]?
If so, that would be an inconsistency between ANSI C89 and ISO C90,
and I didn't think there were any.

Interestingly, a 1988 ANSI C draft ("ansi.c.txt", I'm not sure
where I got it) shows a range of [0, 60].

That's what I consulted; I don't have the actual C90 document.
The footnote reads "The range [0, 60] for tm_sec allows for the
occasional leap second." Perhaps the range shown in the draft
was, er, corrected in the eventual Standard.
 
A

Alan Curry

Thanks a lot for the code.

With posix TZ the days between 12 years is an integer.
With right TZ the days between 12 years have a fractional part.

showtm gives different time_t values for posix TZ and right TZ.

However the time_t is always the same
for 6-30 23:59:60 and 7-1 0:00:00
regardless of the year (leap second or not).
Maybe my Fedora 14 is too old and does not know about the leap second
on 2012-6-30?

That's probably true. Try it with an earlier leap second. The previous June
leap second was in 1997.

Maybe it would have saved some trouble if I posted my output along with the
code. This is from a Debian system with tzdata version 2012g-0squeeze1:

|TZ=posix/Etc/GMT
|Days between now and this time 12 years ago: 4383.0000000000
|This is a leap second:
|2012-6-30 23:59:59 = 1341100799
|2012-6-30 23:59:60 = 1341100800
|2012-7-1 0:00:00 = 1341100800
|This is not a leap second:
|2011-6-30 23:59:59 = 1309478399
|2011-6-30 23:59:60 = 1309478400
|2011-7-1 0:00:00 = 1309478400
|
|TZ=right/Etc/GMT
|Days between now and this time 12 years ago: 4383.0000347222
|This is a leap second:
|2012-6-30 23:59:59 = 1341100823
|2012-6-30 23:59:60 = 1341100824
|2012-7-1 0:00:00 = 1341100825
|This is not a leap second:
|2011-6-30 23:59:59 = 1309478423
|2011-6-30 23:59:60 = 1309478424
|2011-7-1 0:00:00 = 1309478424

The point is that in the TZ=posix/Etc/GMT section there is no way to tell
which year had a leap second, but TZ=right/Etc/GMT reveals it by assigning
different time_t values to 6-30 23:59:60 and 7-1 0:00:00 if and only if the
time with the :60 is a valid leap second.
 
H

Heinrich Wolf

....
That's probably true. Try it with an earlier leap second. The previous
June
leap second was in 1997.

Maybe it would have saved some trouble if I posted my output along with
the
code. This is from a Debian system with tzdata version 2012g-0squeeze1:

|TZ=posix/Etc/GMT
|Days between now and this time 12 years ago: 4383.0000000000
|This is a leap second:
|2012-6-30 23:59:59 = 1341100799
|2012-6-30 23:59:60 = 1341100800
|2012-7-1 0:00:00 = 1341100800
|This is not a leap second:
|2011-6-30 23:59:59 = 1309478399
|2011-6-30 23:59:60 = 1309478400
|2011-7-1 0:00:00 = 1309478400
|
|TZ=right/Etc/GMT
|Days between now and this time 12 years ago: 4383.0000347222
|This is a leap second:
|2012-6-30 23:59:59 = 1341100823
|2012-6-30 23:59:60 = 1341100824
|2012-7-1 0:00:00 = 1341100825
|This is not a leap second:
|2011-6-30 23:59:59 = 1309478423
|2011-6-30 23:59:60 = 1309478424
|2011-7-1 0:00:00 = 1309478424
....
I added another leap second to the code and now have this output:
TZ=posix/Etc/GMT
Days between now and this time 12 years ago: 4383.0000000000
This is a leap second:
2012-6-30 23:59:59 = 1341100799
2012-6-30 23:59:60 = 1341100800
2012-7-1 0:00:00 = 1341100800
This is not a leap second:
2011-6-30 23:59:59 = 1309478399
2011-6-30 23:59:60 = 1309478400
2011-7-1 0:00:00 = 1309478400
This is a leap second:
2008-12-31 23:59:59 = 1230767999
2008-12-30 23:59:60 = 1230681600
2009-1-1 0:00:00 = 1230768000

TZ=right/Etc/GMT
Days between now and this time 12 years ago: 4383.0000231481
This is a leap second:
2012-6-30 23:59:59 = 1341100823
2012-6-30 23:59:60 = 1341100824
2012-7-1 0:00:00 = 1341100824
This is not a leap second:
2011-6-30 23:59:59 = 1309478423
2011-6-30 23:59:60 = 1309478424
2011-7-1 0:00:00 = 1309478424
This is a leap second:
2008-12-31 23:59:59 = 1230768022
2008-12-30 23:59:60 = 1230681623
2009-1-1 0:00:00 = 1230768024
 
S

sla29970

|TZ=posix/Etc/GMT
|Days between now and this time 12 years ago: 4383.0000000000
|TZ=right/Etc/GMT
|Days between now and this time 12 years ago: 4383.0000347222

Hidden in this code lies the semantic issue that has confounded the processof re-thinking leap seconds over the past decade. What is a "Day"? The first example is (for practical purposes) counting mean solar days determined by measuring the rotation of the earth. The second example is counting "atomic" days, chunks of 86400 seconds determined by measuring cesium and other atoms near the surface of earth.

The international agreements on measurements currently have the second (without modifying adjective) defined by cesium, and the day (without modifyingadjective) defined by earth rotation. That means the two are unrelated toeach other. The leap second exists to allow seconds to be measured with atomic precision while also keeping the count of calendar days in step with earth rotation. Alas for kernel hackers, that dichotomy remains an obstacle to new international agreements.

The above example shows the confusion, for the first case means "(mean solar) Days" and the second case means "atomic Days", and both cases base theircalendar on the time scale UTC. Every time scale other than UTC always has 86400 of its own form of seconds in its own form of day.
 
A

Alan Curry

This is a leap second:
2008-12-31 23:59:59 = 1230767999
2008-12-30 23:59:60 = 1230681600
2009-1-1 0:00:00 = 1230768000

You shouldn't be using 12-30. That's a day before the leap second.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top