Proposal for custom time string formatting in std.datetime

Jonathan M Davis jmdavisProg at gmx.com
Tue Dec 27 02:50:06 PST 2011


On Tuesday, December 27, 2011 11:19:03 Kagamin wrote:
> > The core issue with not carrying around a time zone is that you
> > get conversion problems. People do dumb stuff like convert
> > time_t values from UTC to local time and back again, which
> > causes all kinds of bugs.
> 
> Can you elaborate?

1. Any time you do a conversion of any kind, you risk screwing it up. The less 
converting you do, the better.

2. With regards to time, DST is a killer. The reason for this is the fact that 
in the spring, one hour gets skipped, and in the fall one hour happens twice.

So, for example, let's say that in a particular time zone, at 2 am on March 
3rd, the time goes to 3 am to apply DST. That means that the times of 2 am up 
to (but not including) 3 am do not exist. So, if you have the time 2:30 am in 
local time, what time is that in UTC? It's likely that the time code will 
assume that it's really 3:30 am, but the time that you're trying to convert 
doesn't technically exist, so there is not actually a right answer.

On the other hand, let's say that on 2 am on October 30th, the time falls back 
to 1:00 am taking that time zone out of DST. That means that the times of 1 am 
up to (but not including) 2 am happen twice. So, if you have the time 1:30 am 
in local time, what time is it in UTC? You can't know. It could be either. The 
time code is going to have to pick one or the other, but since 1:30 am is non-
unique, it's not necessarily going to have the behavior which is correct for 
your program.

However, UTC can _always_ be correctly converted to other time zones whether 
they have DST or not. This is because UTC does not have DST and therefore does 
not have hours that don't exist or hours that happen twice. All of its times 
are unique. So, if you want to deal with time accurately and reliably, you 
need to always keep the time in UTC until you _need_ to convert it to local 
time (typically for display purposes but also for things like if you need to 
know something along the lines of what year that time is in in the local time 
zone).

Code which converts time back and forth between UTC and local time is asking 
for trouble. Even if it gets all of the conversions correct (or at least as 
correct as possible), it's going to have issues whenever a DST change occurs. 
That's one of the reasons why non-Windows OSes typically want to put the 
system clock in UTC and what it's so horrible that Windows normally puts the 
system clock in local time (another is the fact that applying DST can make it 
so that files from a few minutes ago are suddenly in the future if the file 
timestamps are in local time).

Where I work, we ended up with a bug where when you rewinded video and you 
were east of UTC, it would rewind one hour too far for each hour east of UTC 
that you were (so 2 hours east of UTC would rewind 2 hours and 1 second 
instead of 1 second). It turns out that the code had been converting a time 
value to UTC from local time when it was already in UTC (or it might have been 
the other way around - I don't recall exactly which at the moment). And that 
meant that it was subtracting the UTC offset from the time, causing it to go 
back too far. The only reason that we hadn't seen it in the US was because 
west of UTC, the time would have been in the future, which it couldn't do, so 
it ended up rewinding properly. Had that code completely avoided all of the 
time conversions that it was doing, it wouldn't have had any issues like that. 
And the fact that the bug only manifested in certain time zones (and _not_ the 
time zones that the code was being developed in) made it that much worse.

Times should be kept in UTC as much as possible and converted as little as 
possible. Anything else is asking for trouble. That's also one reason why it's 
good to have times be objects rather than naked numbers. It reduces the risk 
of people converting them incorrectly. SysTime mostly avoids the whole issue 
by encapsulating the time (in UTC) with a time zone, making it so that it 
generally "just works."

- Jonathan M Davis


More information about the Digitalmars-d mailing list