Friday, November 2, 2007

Date Misunderstandings

One of the advantages of Open Source software is that you can look through the code source to figure out what is happening. The concomitant problem is that you often have to look through the source to figure out what it does because the documentation is rarely good enough. The only consolation is that the source code is probably in good shape because you can browse it. Even so, every so often you find a real doozy.

An important Open Source Java component is the Quartz Enterprise Job Scheduler. It is the only Java component that does real job scheduling, and it is both well written and well maintained. I was looking through some of their code the other day to check that it would do what I wanted it to do, when I found this function in the TriggerUtils class:

public static Date translateTime(Date date, TimeZone src, TimeZone dest)

The problem with this function is that the value in a Java Date object does not change when you go from one time zone to another as I explained in the previous post. Yet this function not only seems to suggest otherwise, it actually changes the the value in the Date object based on the time zone offsets, so it is obviously wrong. Fortunately the function is not actually used in any Quartz code, however its very presence suggests that the people who wrote the Quartz code do not fully understand the elements that they are working with.

It may be that the translateTime function was written before Java had the Calendar class, when Date had to do a lot more heavy lifting that it was designed for, but that time has passed and most of the methods in Date have been deprecated. This method should be deprecated as well.

Sunday, September 30, 2007

Java Date, Calendar

Of all the dimensions, time is the most difficult to deal with. Here are my notes on the Java Date and Calendar classes. I will do a separate post on time zone.

Date is an absolute measure of the time. It is a measure of the number of milliseconds that have elapsed since the Epoch. Date is the same where ever you are on earth. As far as I know the the only inaccuracy is that it does not account for leap seconds, but then we have not had many leap seconds recently.

Date has no concept of time zone. You can safely send a Date from one system to another in a different time zone and the Date is unchanged and still correct. You may be confused by the fact that calling toString on Date in some versions of Java will produce a localized string with the time in your time zone. The toString call does this by asking the environment for the time zone. I think that this is very confusing behavior. It would be better if toString displayed the time according to the ISO 8601 standard.

Calender is a Date and a TimeZone. The TimeZone is used when making changes to the time value in the date. Realize that there is a difference between adding 24 hours to a Date and adding a day. If the day happens to span the time change to or from daylight savings time, you have to add 23 or 25 hours to the Date to get to the same time in the next day.

Calendar also deals with other time conundrums like adding a month. Say you are on the 31 of January and add a month, where do you end up? Calendar can give you the 28th of February if you set it up right. Calendar does have its limitations, you cannot add half a day and you have to be careful to use the correct unit when rolling time.

Here is a Java code fragment to format a Date correctly:

SimpleDateFormat ISO8601 =
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
ISO8601.setTimeZone(TimeZone.getTimeZone("UTC"));
String zuluTime = ISO8601.format(new Date());