PermGenError PermGenError - 8 months ago 43
Java Question

TimeZone with Calendar confusing results

I have been working with timezone conversions lately and am quite astonished by the result i get.Basically, i want to convert a date from one timezone into another. below is the code, conversions working fine, but what i have observed while debugging is, the date is not converted unless i call


private static void convertTimeZone(String date, String time, TimeZone fromTimezone, TimeZone toTimeZone){
Calendar cal = Calendar.getInstance(fromTimezone);
String[] dateSplit = null;
String[] timeSplit = null;
if(time !=null){
timeSplit = time.split(":");
dateSplit = date.split("/");
if(dateSplit !=null){
cal.set(Calendar.DATE, Integer.parseInt(dateSplit[0]));
cal.set(Calendar.MONTH, Integer.parseInt(dateSplit[1])-1);
cal.set(Calendar.YEAR, Integer.parseInt(dateSplit[2]));
if(timeSplit !=null){
cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(timeSplit[0]));
cal.set(Calendar.MINUTE, Integer.parseInt(timeSplit[1]));

// System.out.println("Time in " + fromTimezone.getDisplayName() + " : " + cal.get(Calendar.DATE) +"/"+ (cal.get(Calendar.MONTH)+1)+"/"+ cal.get(Calendar.YEAR) +" " + ((cal.get(Calendar.HOUR_OF_DAY)<10) ? ("0"+cal.get(Calendar.HOUR_OF_DAY) ): (cal.get(Calendar.HOUR_OF_DAY)))
// +":" + (cal.get(Calendar.MINUTE)<10 ? "0"+cal.get(Calendar.MINUTE) : cal.get(Calendar.MINUTE)) );
System.out.println("Time in " + toTimeZone.getDisplayName() + " : " + cal.get(Calendar.DATE) +"/"+ (cal.get(Calendar.MONTH)+1)+"/"+ cal.get(Calendar.YEAR) +" " + ((cal.get(Calendar.HOUR_OF_DAY)<10) ? ("0"+cal.get(Calendar.HOUR_OF_DAY) ): (cal.get(Calendar.HOUR_OF_DAY)))
+":" + (cal.get(Calendar.MINUTE)<10 ? "0"+cal.get(Calendar.MINUTE) : cal.get(Calendar.MINUTE)) );

public static void main(String[] args) throws ParseException {

convertTimeZone("23/04/2013", "23:00", TimeZone.getTimeZone("EST5EDT"), TimeZone.getTimeZone("GB"));

Expected Output:
Time in Greenwich Mean Time : 24/4/2013 04:00

Output i got when i comment sysout 1:
Time in Greenwich Mean Time : 23/4/2013 23:00

If i un-comment sysout1 i get the expected valid output.

Any help is appreciated


The internal representation of the given date is not evaluated until really needed, that is until you try to access it by those getters. However the best way of parsing dates is through SimpleDateFormat.

EDIT (added for summarize the comments below and to better clarify my answer).

Calendar works this way for better efficiency: instead of recalculate everithing each time you call a setter, it waits until you call a getter.

Calendar should be used mainly for date calculations (see add() and roll()), but you are using it for parsing and formatting: these tasks are better accomplished with SimpleDateFormat, that's why I say that your usage of Calendar is not elegant.

See this example:

private static void convertTimeZone(String date, String time,
            TimeZone fromTimezone, TimeZone toTimeZone) throws ParseException {
    SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm");
    Date d = df.parse(date + " " + time);
    System.out.println("Time in " + toTimeZone.getDisplayName() + " : " +

I have reimplemented your method using SimpleDateFormat only. My method is smaller, there is no splitting logic (it's hidden in parse()), and also the output is handled in a simpler way. Furthermore the date format is expressed in a compact and standard way that can be easily internationalized using a ResourceBundle.

Also note that the timezone conversion is just a formatting task: the internal representation of the parsed date does not change.