Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java GregorianCalendar change TimeZone

I'm trying to set HOUR_OF_DAY field and change Timezone of the GregorianCalendar date object.

GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("GMT+10"));
System.out.println("HOUR: " + date.get(Calendar.HOUR_OF_DAY));
date.set(Calendar.HOUR_OF_DAY, 23);
//date.get(Calendar.HOUR_OF_DAY);
date.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("HOUR: " + date.get(Calendar.HOUR_OF_DAY));

Output:

HOUR: 16
HOUR: 23

For some reason value of HOUR_OF_DAY does not change after setting different timezone. But if I uncomment date.get for HOUR_OF_DAY, everything works exactly as it should

GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("GMT+10"));
System.out.println("HOUR: " + date.get(Calendar.HOUR_OF_DAY));
date.set(Calendar.HOUR_OF_DAY, 23);
date.get(Calendar.HOUR_OF_DAY); // uncommenting this line will is changing the output
date.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("HOUR: " + date.get(Calendar.HOUR_OF_DAY));

Output:

HOUR: 16
HOUR: 13

How is this possible? Why .get method is changing object behaviour?

like image 337
Alexander Allakhverdiyev Avatar asked Aug 27 '12 06:08

Alexander Allakhverdiyev


1 Answers

The GregorianCalendar class inherits its get method from Calendar, which has the following side effect:

In lenient mode, all calendar fields are normalized.

This means that the time value and all fields are recomputed when get is called on a Calendar object. This can lead to some unpredictable behavior, particularly when coupled with setTimeZone, which has some documented buggy behavior of its own.

like image 135
Bill the Lizard Avatar answered Nov 06 '22 03:11

Bill the Lizard