JDK-4827490 : (cal) Doc: Calendar.setTimeZone behavior undocumented
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:i18n
  • Affected Version: 1.4.0,1.4.1
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: linux,solaris_9,windows_2000
  • CPU: x86,sparc
  • Submitted: 2003-03-05
  • Updated: 2017-02-10
Related Reports
Duplicate :  
Description
My java file:

import java.util.*;
public class calTest
{
  public static void main(String argv[]) {
    TimeZone tz = TimeZone.getTimeZone("GMT");
    //my locate is Asia/Shanghai(GMT+8:00), so the following code set the cal to
    //20030301T160000Z
    Calendar cal = new GregorianCalendar(2003,2,2,0,0,0);
    cal.setTimeZone(tz);  //now the timezone change from Aisa/Shanghai to GMT
    cal.set(Calendar.HOUR_OF_DAY,0);  //in GMT, set the hour to 0
    //so the cal should be now 20030301T000000Z
    System.out.println(     cal.get(Calendar.DAY_OF_MONTH) + "--" + cal.get(Calendar.HOUR_OF_DAY));
  }
}

Expecting output:
1--0
Real output:
2--0
In fact, the cal now is 20030302T000000Z, but not 20030301T000000Z which is my expectation.

Comments
WORK AROUND between cal.setTimeZone(); and cal.set(Calendar.HOUR_OF_DAY,0); add cal.get(Calendar.HOUR_OF_DAY); the result is right. i.e. after changing the time zone, we must call some read method, such as get(*); before we call other write method, such as set(*);
06-08-2004

EVALUATION The setTimeZone call may change the Calendar fields and therefore changes the internal state that the fields must be recalculated from the millisecond value. The next set(HOUR_OF_DAY, 0) call invalidates the millisecond value. At this point the Calendar object has to rely on the initial field values that once have been determined to need to be recalculated. So, it's necessary to call get(int) to cause the field calculation after setting the time zone. This behavior isn't described. This bug report remains as a documentation problem. ###@###.### 2003-03-06 The milliseconds cache is intended to increase performance, not to produce non-intuitive results. Unlike other attributes, the setTimeZone() method affects how every field is interpreted. GregorianCalendar should update the milliSeconds cached value automatically. Note that add() already does this, so there is a precedent. ###@###.### 2003-03-10 Please provide a business justification that the setTimeZone behavior must be changed even there is a risk of breaking existing applications. I need to get approval on this incompatible API change for the fix. ###@###.### 2003-03-11 I have no additional business justification for this bug, other than the bug description and my comments above. It is clear that it takes both experimentation and careful reading of the documentation to be able to use the java Calendar classes effectively. ###@###.### 2003-03-11 The documentation will be fixed. (No behavior change will be made.) ###@###.### 2003-04-23
11-03-2003