FULL PRODUCT VERSION :
java version "1.6.0_24"
Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
Java HotSpot(TM) Client VM (build 19.1-b02, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Windows XP Version 2002 SP3
A DESCRIPTION OF THE PROBLEM :
Check this example:
public static void main(String[] args) {
List<Calendar> c = new ArrayList<Calendar>(3);
c.add(createCalendar(TimeZone.getTimeZone("Europe/Zagreb")));
c.add(createCalendar(TimeZone.getTimeZone("Europe/Ljubljana")));
c.add(createCalendar(TimeZone.getTimeZone("Europe/London")));
c.add(createCalendar(TimeZone.getTimeZone("UTC")));
for (Calendar cal : c) {
cal.setTimeInMillis(1256428800000L);
System.out.println("pre="+cal.getTime() + " H="+cal.get(Calendar.HOUR) + " H_OF_DAY="+cal.get(Calendar.HOUR_OF_DAY) + " MIN=" + cal.get(Calendar.MINUTE) + " "+cal.getTimeInMillis());
//cal.set(Calendar.DST_OFFSET, cal.get(Calendar.DST_OFFSET));
cal.set(Calendar.MINUTE, 0); // HERE IS BUG
System.out.println("p0="+cal.getTime() + " H="+cal.get(Calendar.HOUR) + " H_OF_DAY="+cal.get(Calendar.HOUR_OF_DAY) + " MIN=" + cal.get(Calendar.MINUTE) + " "+cal.getTimeInMillis());
}
}
As you see, all times are rounded by HOUR, so MINUTE = 0
If you set VM parameter -Duser.timezone=UTC you see a BUG.
The method cal.set should set the MINUTE field to ZERO and before that it has allready been a ZERO (practically dummy action), so nothing should change.
But it DOES!!!
Time shift's one HOUR forward for all calendars except the one created with UTC TimeZone.
It will also happen if you try to set SECOND and MILISECOND to 0 (before also allready 0).
Actually Calendar's local_fields don't change, but TimeInMillis DO change.
Strange.
But if you uncomment the line where the DST_OFFSET is set (as it is get, so actually doing nothing) everything works fine for any -Duser.timezone ARGUMENT.
I read the Calendar's documentation and part where it is described the calculation of millis and local_fields and round trips (when necessary).
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. run the example => BUG
2. uncomment (the only commented line) => worx fine
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
1.
If Calendar field MINUTE is = 0, I expect setting Calendar field MINUTE again to 0 (practically dummy action) would NOT change HOUR field !!!
Hour field going up by 1 is BUG.
2.
Why would setting DST field to an existing value correct this BUG ... ?
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public static void main(String[] args) {
List<Calendar> c = new ArrayList<Calendar>(3);
c.add(createCalendar(TimeZone.getTimeZone("Europe/Zagreb")));
c.add(createCalendar(TimeZone.getTimeZone("Europe/Ljubljana")));
c.add(createCalendar(TimeZone.getTimeZone("Europe/London")));
c.add(createCalendar(TimeZone.getTimeZone("UTC")));
for (Calendar cal : c) {
cal.setTimeInMillis(1256428800000L);
System.out.println("pre="+cal.getTime() + " H="+cal.get(Calendar.HOUR) + " H_OF_DAY="+cal.get(Calendar.HOUR_OF_DAY) + " MIN=" + cal.get(Calendar.MINUTE) + " "+cal.getTimeInMillis());
//cal.set(Calendar.DST_OFFSET, cal.get(Calendar.DST_OFFSET));
cal.set(Calendar.MINUTE, 0); // HERE IS BUG
System.out.println("p0="+cal.getTime() + " H="+cal.get(Calendar.HOUR) + " H_OF_DAY="+cal.get(Calendar.HOUR_OF_DAY) + " MIN=" + cal.get(Calendar.MINUTE) + " "+cal.getTimeInMillis());
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
uncomment (the only that is commented)