Beware of the timezone

The country of Samoa has decided to skip a day, the 30th of december 2011 doesn't exist on Samoa. This decision was driven by economical reasons. I wonder, what potential problems we can run into regarding software development for our IT systems depending on timezone information?

To skip a day, it all sounds so easy. First of all i was curious to know if similar situations have occured in the past and what the software development pitfalls could be. A small investigation showed me that you need to be careful with assumptions regarding regional timezone issues. Let's have look at how a programming language like JAVA handles these kinds of situations.

To demonstrate the consequences of this kind of detailed timezone changes and how JAVA handles them, i have compiled the following example (Apia is the capital of Samoa):
1. TimeZone timeZoneApia = TimeZone.getTimeZone("Pacific/Apia");
2. SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
3. sdf.setTimeZone(timeZoneApia);
4. Calendar calendar = new GregorianCalendar(timeZoneApia);
5. calendar.set(2011, 11, 29, 23, 59, 59);
6. System.out.println(sdf.format(calendar.getTime()));

Obviously, the output of line 6 is:
29-12-2011 23:59:59
Now, let's add the following lines:
7. calendar.add(Calendar.SECOND, 1);
8. System.out.println(sdf.format(calendar.getTime()));

The output of line 8 depends on the JAVA 7 version you use. If you use the original released JAVA 7 or JAVA 7 update 1, the output will be:
30-12-2011 00:00:00
If you run JAVA 7 update 2 (or if you are running a previous version of JAVA 7 and have updated the timezone configuration) the output will be:
31-12-2011 00:00:00
This example demonstrates how well JAVA has implemented their timezone awareness.

JAVA 7 update 1 was released on the 18th of october 2011, the "Samoa case" was not included here. However, Oracle provides a tool called Timezone Update Tool to update your JAVA timezone configuration. The changelog of the tool gives a nice overview of recent timezone changes. I was suprised by the amount of updates regarding timezones.

This made me curious about other, similar, cases. I found a number of cases and would like to point out one interesting case in the Netherlands where they did not skip a whole day but only a couple of seconds.

Consider the following example:
1. TimeZone timeZoneAmsterdam = TimeZone.getTimeZone("Europe/Amsterdam");
2. SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
3. sdf.setTimeZone(timeZoneAmsterdam);
4. calendar = new GregorianCalendar(timeZoneAmsterdam);
5. calendar.set(1937, 5, 30, 23, 59, 59);
6. System.out.println(sdf.format(calendar.getTime()));

Obviously, the output of line 6 is:
30-06-1937 23:59:59
Now, let's to the same trick as with the "Samoa case". Add the following lines:
7. calendar.add(Calendar.SECOND, 1);
8. System.out.println(sdf.format(calendar.getTime()));

Question: What will be the output of line 8?

The correct answer is:
01-07-1937 00:00:28
The short story behind this: in the early 1900s the Dutch government declared that the official time in the Netherlands was "Amsterdam Time". To be more specific, the meridian of the "Westertoren" in Amsterdam. This resulted in an offset of 19 minutes and 32 seconds with GMT.

On the 1st of July 1937 it was decided that the offset with GMT should be 20 minutes, creating a 28 second gap. So, officially, the first 28 seconds of the July 1st 1937 do not exist in the Netherlands. Probably, in 1937, not so many people were worried about the possible IT consequences of such a decision.

Conclusion

With this article i wanted to show that, especially in IT, you need to be careful about assumptions regarding calendar and timezone related issues. Hard to spot errors may be around the corner without realizing it. For example, when constructing a Calendar for a date/time/timezone combination that does not exists, the following happens:

  • JAVA returns a date which is "rounded off" to the nearest valid value in the future (we have seen this in both examples in this article)
  • If you don't want JAVA to return the nearest valid value in the future, please set the value of the Lienient property to false and you will receive an exception instead of the nearest valid value in the future.

Comments (0)

    Add a Comment