std.date

Jonathan M Davis jmdavisProg at gmx.com
Wed Nov 17 10:29:30 PST 2010


On Wednesday, November 17, 2010 09:51:30 Jonathan M Davis wrote:
> On Wednesday, November 17, 2010 04:15:52 Kagamin wrote:
> > Daniel Gibson Wrote:
> > > > Synchronization can fail if the code asserts that number of seconds
> > > > is not greater than 59 (Jonathan's lib does the same, I think). Is
> > > > it the cause?
> > > 
> > > How are leap seconds handled on a computer anyway? Does the clock
> > > really count to 60 seconds (instead of 59) before the next minute
> > > starts, or is the clock just slowed down a bit (like it's - IIRC -
> > > done when changing the time with NTP or such)?
> > 
> > This is how it looked on linux:
> > 
> > bash-2.05b# date
> > Thu Jan 1 00:59:58 CET 2009
> > bash-2.05b# date
> > Thu Jan 1 00:59:59 CET 2009
> > bash-2.05b# date
> > Thu Jan 1 00:59:60 CET 2009
> > bash-2.05b# date
> > Thu Jan 1 01:00:00 CET 2009
> > bash-2.05b# date
> > Thu Jan 1 01:00:01 CET 2009
> > bash-2.05b#
> 
> That's the standard, but supposedly it varies a bit in how it's handled -
> at least if you read it up on Wikipedia.
> 
> I'd have to go digging in std.datetime again to see exactly what would
> happen on a leap second, but IIRC you end up with either 59 twice or 00
> twice. Unix time specifically ignores leap seconds, and in 99.9999999999%
> of situations, if you have a 60th second, it's a programming error, so
> TimeOfDay considers 60 to be outside of its range and throws if you try
> and set its second to 60.
> 
> SysTime is really the only type where it would make much sense to worry
> about leap seconds, but since the only way that you're going to get them
> is if you go out of your way by using a PosixTimeZone which starts with
> "right/" for your time zone, it seemed silly to worry about it overly
> much. The _system time_ ignores leap seconds after all, _even_ if you use
> one of the time zones that starts with "right/" as your system's time
> zone. So, the result is that if you use one of the PosixTimeZones with
> leap seconds, it will correctly adjust for leap seconds except when adding
> or removing a leap second, at which point, you'd get a duplicate time for
> two seconds in a row in the case of an addition and probably would skip a
> second in the case of subtraction (though that's actually probably the
> correct behavior for a subtraction - not that they've ever subtracted an
> leap seconds yet). It might be less than ideal if you _really_ care about
> leap seconds, but allowing for a 60th second could really mess with
> calculations and allow for bugs to go uncaught in user code. So, allowing
> for a 60th second when adding a leap second would help an extreme corner
> case at the cost of harming the normal case, and I decided against it.

Actually, this results in the entertaining situation where you can have two 
SysTimes which convert to identical strings but where one is less than the other 
when compared (because their internal times are in unadjusted UTC and would 
differ). Of course, you'd have to get two times which were exactly 1 second 
apart, and their precision is 100 ns (though it only manages microsecond 
precision on Linux since that's as precise as the system clock is; I believe 
that Windows is slightly higher precision but not the full 100 ns), so the odds 
of it happening aren't terribly high, but it is technically possible. I suppose 
that if you got a bug because of it, it would be because you were converting all 
of your times to strings, and your program couldn't deal with the fact that your 
strings were suddenly 1 second back in time. Other than that, I don't expect 
that it would result in a problem. And since the clock can do that _anyway_ when 
it's adjusted for skew by NTP, I don't see that as being all that big a deal 
(though in the case of adjusting for NTP, the internal stdTimes for the SysTimes 
would be off as well, while in the leap second case, they aren't).

- Jonathan M Davis


More information about the Digitalmars-d mailing list