Since the US just changed time zone, and the EU will be changing time zone soon, it seems like a good time to refresh an old posting of mine about dates and times, and how hard it can be to do the right things with them in software.

I’ve spent a lot of my career in the computer industry working on computer-based calendar systems and organizers of various kinds. Here are a few pitfalls to be aware of.

  • Time zones expressed as letters (e.g. CST) are ambiguous, and hence useless.
  • Time zone offsets are not always an exact number of hours.
  • Both 00:00 and 24:00 are valid times (as per ISO) and refer to different moments of a given date. 00:00 is the midnight which begins the day, 24:00 is the midnight which ends it, and is also 00:00 of the next day.
  • Rounding of durations isn’t obvious. People expect a duration in hours or minutes to be rounded to the nearest unit, up or down. However, they expect a duration in days to always be rounded up. Even if the event finishes after one hour of the final day, that day still counts towards the event duration.
  • Minutes do not always consist of 60 seconds. Sometimes there are leap seconds. For example, 2005 had a leap second on December 31st, and so did 2008. Or to look at it another way…
  • Never store time as a number of seconds from an ’epoch’ date.

All of our local time zones are defined as offsets from UTC. For precision, UTC is defined by atomic clocks, whereas older time standards such as GMT were based on astronomical observations. However, UTC is kept in sync with older time standards by having leap seconds added or subtracted as necessary. Whenever UTC drifts far enough from UT1 or astronomical time, a leap second is scheduled.

Lots of systems store the date and time as the number of seconds since (say) January 1st 1970. The problem is, the exact dates on which the leap seconds in our calendar will occur cannot be determined in advance, because they depend upon the subtly varying rotational speed of the earth. The earth’s rotation changed measurably after the 2004 tsunami in Asia, for example. Hence given a date and time in the future, there is no way to calculate how to represent it exactly as a number of seconds from an epoch moment.

Another way of looking at it, is that if you have any epoch dates in 2006 stored in your computer, they’re now going to be off by a second because of the leap second announced for 2005, until your date and time library is updated.

Of course, you can ignore leap seconds. But if you do, any calculation that asks for the number of seconds between two moments in time may give the wrong answer. It won’t be very wrong, just a few seconds off, but that might be wrong enough to cause a very expensive error. (See The Fractious Leap Second Debate for more on this subject.)

It’s also really difficult to get the right values of epoch time internationally, as different countries have different numbers of legally counted leap seconds.

Continuing the list:

  • Leap years. February. Get it right, OK?
  • Time stamps should never be given in local time unless you also specify the time zone for every single time stamp. Otherwise, your timestamps are ambiguous for the hour which recurs when people switch back from daylight savings time to standard time.

Consider the following sequence:

Oct 31 01:55 Log in from 192.168.0.1  
Oct 31 02:05 Log in from 192.168.0.2

Are these two events 10 minutes apart, or 70 minutes apart? Without the time zone information, you have no way to tell.

Of course, the right thing to do is timestamp in UTC.

On a related note:

  • You must always store a time zone along with a date, even if the date has no associated time.

The reason for this is simple: June 5th in Australia is not the same day as June 5th in San Jose. Specifically, June 5th in Australia is ending and everyone’s going to bed before June 5th in San Jose gets started. An event that happens on June 5th in Australia may happen on June 4th in San Jose, so you need to know the time zone of the event in order to display the date correctly to the user.

If you don’t store a time zone, then basically there’s an implicit time zone, most likely the time zone that will be in effect on the date in question, at the location where the date is being measured. For an event, that will be the location where the event is happening. Obviously, implicit time zones aren’t very helpful for end users distant from the event in question, because they have to (a) realize without prompting that the correction has to be made and the date has to be adjusted, and (b) guess what the time zone is and how it will affect the date as seen from their time zone.

In Lotus Notes, you’ll need to use a formula like this:

ost := @If(StartTime = ""; @Time(9; 0; 0); @Time(StartTime)); 
tm := @TimeMerge(StartDate; ost; TimeZone); 
@If(StartTime = ""; @Date(tm); tm);

This treats a date with no time as being basically the same as a date starting at 9am in the appropriate time zone. The choice of 9am is arbitrary and based on conventional business hours; there’s no answer which is always precisely correct.

In other words…

  • Automatically adjusting dates and times in a calendar is hard. People often complain because their electronic calendar gives them the wrong answer when they fly half way across the world and change time zone. They think it’s a fault in the software, and that it must be badly designed. The truth is that there is no right answer.

Consider the following schedule:

2004-10-10 10:00 Team conference call.
2004-10-10 12:00 Lunch with Mike.
2004-10-10 13:00 Conference session 2: Designing Groupware

Suppose Mike and I fly 8 hours west. What happens? The first item on my schedule is a phone call. It happens at the same instant in universal time, no matter where I happen to be. Therefore to show me the right time, the software has to shift the displayed time by 8 hours. It might have to shift the date too, as a result.

The second item on my calendar is going to happen at noon in whatever time zone Mike and I happen to be in as we travel. We may not even know in advance what that time zone is going to be. So the right thing for the software to do is probably not to shift the time at all.

The third item is a physical event, but in this case the time and date are always going to be relative to the time zone in effect at the location where the event is taking place. So, the correct thing to do is almost certainly to leave the date and time alone.

So should the software adjust the display of the dates and times in this example? The “correct” answer is “definitely yes, maybe, and definitely not”.

One approach might be to have a flag in each event specifying whether the time and date should be corrected when the user changes time zone, or whether they should be allowed to float and effectively change. The flag could be part of the time zone field — if you specify a time zone field the date and time are adjusted, otherwise they float. I’ve never seen an electronic organizer that actually worked that way, though.

Lotus Notes does not change the time and date of an event when you change time zone. This is a common misconception. Notes actually leaves the date and time exactly the same; it is not modified in any way. An event stored and displayed as starting at instant T, is still stored and displayed as starting at instant T. However, the way instant T is indicated depends on what time zone you are in, so it looks like a different time or date, but it actually isn’t.

In contrast, the Palm OS date book does alter all the times and dates when you change time zones. If you change the time zone from San Jose to Australia, the system date and time will change, but all your events will be moved. If you set an alarm for a net radio show or a conference call, the alarm will probably happen at the wrong time. See immediately above for more explanation.