Saturday, August 7, 2010

Java Puzzler: 1 July 1937

In this blog post I will discuss the idiosyncrasies of Java and the date of 1 July 1937 in the Netherlands. I encountered this as a bug at work.

Look at the following code. Note that my timezone is set to Europe/Amsterdam.

Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(1937, 5, 30, 23, 59, 59);
System.out.println(calendar.getTime());

System.out.println(calendar.getTime());


I will tell you the output of line 4. It is Wed Jun 30 23:59:59 CEST 1937. What would you expect to be the output of line 7?
If somebody would ask me this question, I would be very suspicious. Why ask this question if the answer should obviously be Thu Jul 01 00:00:00 CEST 1937? What is going on here? But for me, without resorting to psychology, there is no other answer thinkable then the obvious.

As it turns out the answer on my machine consistently is: Thu Jul 01 00:00:28 CEST 1937.

The crucial piece of information is that the timezone is set to Europe/Amsterdam. With the timezone set to something else e.g. Europe/London, the output is the expected Thu Jul 01 00:00:00 BST 1937. So what is going on here?

As it turns out, on 1 July 1937 the dutch government decided to changed meridians for timekeeping. Apparently in 1908 a the government introduced a national means to keep time. The time in the Netherlands was determined by the time in Amsterdam. At first the Westertoren was picked as defining meridian (4° 53' 01.95" east longitude) resulting in a time difference of 19 minutes and 32 seconds with GMT.
On the first of July 1937 the 5° meridian was used to tell time to give an even time difference of 20 minutes with GMT. But this produced a 28 seconds skip in time keeping. So the first 28 seconds of 1 July 1937 do not exist in the Netherlands. This is the cause of the peculiar behavior of the above code.

reference (in dutch).