Kanagavelu Sugumar Kanagavelu Sugumar - 8 months ago 28
Java Question

SimpleDateFormat behaves differently in different timezones JVM

I am following the below code to create a Date object on specified dateTime with a specified Timezone.

Note: I haven't set any timezone for jvm; But testing this code with different linux server timezones.

String date = "20121225 10:00:00";
String timeZoneId = "Asia/Calcutta";
TimeZone timeZone = TimeZone.getTimeZone(timeZoneId);

DateFormat dateFormatLocal = new SimpleDateFormat("yyyyMMdd HH:mm:ss z");
//This date object is given time and given timezone
java.util.Date parsedDate = dateFormatLocal.parse(date + " "
+ timeZone.getDisplayName(false, TimeZone.SHORT));

if (timeZone.inDaylightTime(parsedDate)) {
// We need to re-parse because we don't know if the date
// is DST until it is parsed...
parsedDate = dateFormatLocal.parse(date + " "
+ timeZone.getDisplayName(true, TimeZone.SHORT));

Now parsedDate object behaves differently

When my jvm Server is running in IST

parsedDate.getTime() -- 1356409800000

parsedDate.toString() -- Tue Dec 25 10:00:00 IST 2012

in GMT --- 12/25/2012 04:30:00 GMT

When my jvm Server is running in EST

parsedDate.getTime() -- 1356422400000

parsedDate.toString() -- Tue Dec 25 03:00:00 EST 2012

in GMT --- 12/25/2012 08:00:00 GMT

My both system times are in sync

Mon Dec 24 10:30:04 EST 2012

Mon Dec 24 21:00:48 IST 2012

I am expecting in both machine i should get the same GMT time.

What was wrong here?


The short-name is not a good way to identify a time-zone, because it's not unique; the Javadoc for java.util.TimeZone gives the example that "'CST' could be U.S. 'Central Standard Time' and 'China Standard Time'".

More generally . . . instead of passing the time-zone as a string, so that your DateFormat has to parse it, it makes more sense to just tell your DateFormat what the time-zone is, by using the TimeZone instance that you already have:

    DateFormat dateFormatLocal = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
    java.util.Date parsedDate = dateFormatLocal.parse(date);

(This will also take care of daylight-savings time automatically, to the extent that that's possible.)