Java Calendar Is Broken On JVM Upgrade

We ran into an interesting issue with TimeZone and Dates. If you print the same date on different JVMs, it might show a different printed date.

The reason behind this is the daylight saving time conventions. An old JVM won't necessarily have the same daylight saving time for a given TimeZone than a latest JVM, and therefore will interpret the date differently.

Here is the output of a very simple program on 2 different JVMs. The number is the long number used to represent the date. I only use SimpleDateFormat with different TimeZone:

JVM 1.5.0_12
loading date=Sat Jul 18 06:59:36 CEST 2009, number=1247893176505
using formatter in EST: 7/17/09 11:59 PM
using formatter in Asia/Singapore: 7/18/09 12:59 PM

JVM 1.5.0_20
loading date=Sat Jul 18 06:59:36 CEST 2009, number=1247893176505
using formatter in EST: 7/18/09 12:59 AM
using formatter in Asia/Singapore: 7/18/09 12:59 PM

The source code:

public class DateBug {

private static String FILE_NAME = "datebug.txt";

public static void load() throws IOException {
FileReader fr = new FileReader(FILE_NAME);
BufferedReader br = new BufferedReader(fr);
String l = br.readLine();
br.close();
long time = new Long(l);
Date d = new Date(time);
System.out.println("loading date="+d+", number="+d.getTime());
SimpleDateFormat formatter = new SimpleDateFormat();
formatter.setTimeZone(TimeZone.getTimeZone("EST"));
System.out.println("using formatter in EST: "+formatter.format(d));
formatter.setTimeZone(TimeZone.getTimeZone("Asia/Singapore"));
System.out.println("using formatter in Asia/Singapore: "+formatter.format(d));
}

public static void saveNew() throws IOException {
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("EST"));
c.set(2009, 06, 17, 23, 59);
Date d = c.getTime();
System.out.println("saving date="+d+", number="+d.getTime());
SimpleDateFormat formatter = new SimpleDateFormat();
formatter.setTimeZone(TimeZone.getTimeZone("EST"));
System.out.println("using formatter in EST: "+formatter.format(d));
formatter.setTimeZone(TimeZone.getTimeZone("Asia/Singapore"));
System.out.println("using formatter in Asia/Singapore: "+formatter.format(d));

FileWriter fw = new FileWriter(FILE_NAME);
PrintWriter pw = new PrintWriter(fw);
pw.println(d.getTime());
pw.close();
}

public static void main(String[] args) throws IOException {
System.out.println("JVM "+System.getProperty("java.version"));
if (args.length == 1) {
if (args[0].equals("save")) {
saveNew();
}
} else {
load();
}
}
What does this mean? This means that if you entered in a GUI in the first JVM a particular date & time using EST time zone. This will change when you read back in the second JVM.
This suggests that if you want to keep the same dates, you are better off saving in UTC where daylight saving time is not used and trick DateFormat. But I have to say this looks quite ugly.

Comments

comments powered by Disqus