Don't count your seconds before they're hatched

or Why coders hate Daylight Saving Time.

Today marks the end of Daylight Saving Time in the US - what other countries sometimes call
Summer Time. A legislative attempt to reconcile how people use a clock with how the sun behaves seasonally. I'm not really going to debate or discuss the merits vs pitfalls of DST since they're not relevant at the moment, but I'll explore how, as programmers, we can't always assume that certain physical constants are actually constant.

Like the number of seconds between noon on two consecutive days.

The Problem

Most of the time - this isn't really a problem. One day has 24 hours, each hour has 60 minutes, each minute has 60 seconds. That comes to 86400 seconds in a day. What could be simpler?

Except on days like today when DST ends. That means that at 2am Daylight Saving Time it became 1am Standard Time. So between the midnight when the day began and the midnight when it ends, there was an extra hour which corresponds to an extra 3600 seconds. So there are 90000 seconds today. The opposite is true when DST begins - at 2am Standard Time it becomes 3am Daylight Saving Time, so there are only 82800 seconds in the day.

It gets even more confusing when you consider that the rules for DST aren't consistent. The weekend they change has changed over time, and there were even some times when it was in effect year-round. Some locations didn't have DST and have adopted it, while others don't need it for their location.

And don't think this is just about days and odd times of the year. We've gotten used to it, but keep in mind that there are a variable number of days in the year when you consider leap years. And there is a hot debate about the use of the leap second to keep atomic clocks in sync with astronomical clocks.

But so what? Aren't coders wise enough to all this to avoid any problems? Well...

The Impact

There have been a surprising number of cases where this wasn't true. Time and again, operating systems have been wrong on the day after DST begins or ends because they computed it wrong. Many schedulers have done things like failed to run jobs because an hour was skipped over during the change to DST, or run twice during the change away from it.

It gets even more confusing when you throw in time zones and consider that different time zones may apply the DST rules at different times of the year (such as just happened now - Europe and the US left summer time at different times).

For example, what if you're writing a calendar program. One common task is to schedule something for "2:00 every afternoon". A simplistic solution might have you do this:
  • You'll store this task as the time the event first happens in number of seconds since some date (an epoch time).
  • You'll then compute every other time this will happen by adding a multiple of 86400 seconds to that.
So what would that have scheduled?
  • October 30th, 2pm Daylight Saving Time
  • October 31st, 2pm Daylight Saving Time
  • November 1st, 1pm Standard Time
  • November 2nd, 1pm Standard Time
That doesn't look right!

It shows up in other places as well. What if you're writing a program that lets you view how much energy you've used every hour for the day before? Most days will be no problem - 24 hours in the day, 24 lines. But one day a year will have 25 hours, and one day will have 23. How will you show this so it isn't confusing? If someone asks for the 1am reading, what will you return?

The Solution

Well... there isn't one.

There are several tricks we can try, of course, but there is no "one size fits all" solution to this issue. It really depends on the exact case.

For our calendar example above, we need to do the calculations and take Daylight Saving into account. If we're storing it in a database, we'll need to store what we want ("every day at 2pm") rather than the results of the calculation so we can re-calculate if DST rules change.

When it comes to displaying days with more than 24 hours, we just have to be aware that they will happen and leave room for them. For queries for 1am (rare, but they will happen, you can count on that), we need to be able to handle situations where more than one result will be returned or find a way to specify which version of 1am we want - the Standard Time version or the Saving Time version.

Above all, however, we have to keep in mind that this isn't a straightforward issue... and that the time that we're reporting has to be used by people, who are using time in their own ways and for their own purposes.

Don't waste time - keep quirks like these in mind as you program.

No comments:

Post a Comment