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:
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.
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();
}
}
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.
I just found out it happens only with EST, this is a bit surprising. I would have thought a timezone update could have broken other timezones.
ReplyDeleteIt happens that EST is deprecated!
Quote from http://java.sun.com/javase/timezones/DST_faq.html#change :
Can I still use the deprecated three-letter timezone IDs "EST", "HST", and "MST" for Eastern, Hawaii, and Mountain summer time?
No, this can lead to incompatibilities. You should use the new format of timezone ID, for example, "America/New_York." See Background on Sun Alert 102836 for more details.