I observed a strange behaviour of java.util.GregorianCalendar, and I wonder why it behaves so.
I wanted to get the time in UTC, which is the same instant as 26.10.2014 01:00 CET
and then get UTC midnight for the same day. So first I set the actual CET date, than changed the timezone to UTC, and finally set the HOUR_OF_DAY to 0.
Example:
- 26.10.2014 01:00 CET is the same as 25.10.2014 23:00 UTC
- midnight(25.10.2014 23:00 UTC) should be 25.10.2014 00:00 UTC
see junit code below:
@Test
public void testWeird() {
GregorianCalendar date = (GregorianCalendar) GregorianCalendar.getInstance(TimeZone.getTimeZone("CET"));
date.set(2014, 9, 26, 1, 0, 0); //26.10.2014
System.out.println(date.getTime().toGMTString() + " " + date.getTimeInMillis()); // 25 Oct 2014 23:00:00 GMT 1414278000764 (OK)
date.setTimeZone(TimeZone.getTimeZone("UTC"));
//date.get(Calendar.YEAR); // uncomment this line to get different results
System.out.println(date.getTime().toGMTString() + " " + date.getTimeInMillis()); // 25 Oct 2014 23:00:00 GMT 1414278000764 (OK)
date.set(Calendar.HOUR_OF_DAY, 0);
System.out.println(date.getTime().toGMTString() + " " + date.getTimeInMillis()); // 26 Oct 2014 00:00:00 GMT 1414281600764 (NOT OK! why not 25 Oct 2014 00:00:00 GMT 1414195200218 ?)
}
I expected that setting hour=0 on 25.10.2014 23:00 GMT
will give me 25.10.2014 00:00 GMT
, but it changed to 26.10.2014 00:00 GMT
.
However, if I uncomment line date.get(Calendar.YEAR);
, the date seems to be calculated correctly.
The same happens on jdk.1.7.0_10 and jrockit-jdk1.6.0_37.
date.get(Calendar.YEAR);
influences the final result. A bug in JDKs GregorianCalendar? – WronglyCalendar
JavaDoc. This class behaviour is pretty complex. Calling some methods will force calendar to perform timestamp / field calculation, which changes internal state of the calendar and might have some unexpected side effects. – Joleedate.get(...)
calls indirectly the methodcomplete()
wich compute fields, wich are not set at this time. So the object will change. – UdaleDAY_OF_MONTH
is not recalculated properly aftersetTimeZone()
maybe the nextset(HOUR_OF_DAY,0)
is working on incorrect internal state and the change of the day is missed. – Wrongly