JDK-5026826 : Problem setting time zone for GregorianCalendar.
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:i18n
  • Affected Version: 1.4.2
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: linux
  • CPU: x86
  • Submitted: 2004-04-05
  • Updated: 2004-04-06
  • Resolved: 2004-04-06
Description

Name: gm110360			Date: 04/05/2004


FULL PRODUCT VERSION :
java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)

java version "1.4.2_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_04-b05)
Java HotSpot(TM) Client VM (build 1.4.2_04-b05, mixed mode)

java version "1.5.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta-b32c)
Java HotSpot(TM) Client VM (build 1.5.0-beta-b32c, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Linux xxxx.amazon.com 2.4.21-1a #1 Thu Jul 3 15:47:32 PDT 2003 i686 unknown

A DESCRIPTION OF THE PROBLEM :
It seems that creating a new GregorianCalendar and then calling setTimeZone() before calling getTimeInMillis() causes the date to be changed.  Please take a look at the included example.

This is happening with all versions of Java that I have tested.

Thanks!
Kevin Regan
###@###.###


REGRESSION.  Last worked in version tiger-beta

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the included program.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
1083438000000
1083438000000

ACTUAL -
1083438000000
1083412800000

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;

public class TimeTest {

    public static void main(String[] args) {

        Calendar calendar = new GregorianCalendar(2004, 4, 1, 12, 0);
        calendar.getTimeInMillis();
        calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
        System.out.println(calendar.getTimeInMillis());

        Calendar calendar2 = new GregorianCalendar(2004, 4, 1, 12, 0);
        calendar2.setTimeZone(TimeZone.getTimeZone("GMT"));
        System.out.println(calendar2.getTimeInMillis());

    }

} // TimeTest
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
The Calendar.getTimeInMillis() method must be called before the Calendar.setTimeZone() method.
(Incident Review ID: 246417) 
======================================================================

Comments
WORK AROUND Use of the GregorianCalendar(TimeZone) constructor would be less confusing. The sample code in Description can be written as: Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("GMT")); calendar.clear(); calendar.set(2004, 4, 1, 12, 0); Please note that the clear method call is required to clear the SECOND and MILLISECOND values before setting the date and time. ###@###.### 2004-04-06
06-04-2004

EVALUATION In the first case, the getTimeInMillis call requires to calculate the time value (milliseconds from the Epoch) with the default time zone. The setTimeZone call invalidates the calendar field values, and any get method call would cause to recalculate the calendar field values from the time (millisecond) value. This is the reason why the same time (millisecond) value is returned by the second getTimeInMillis method call. In the second case, the getTimeInMillis call causes the time (millisecond) value calculation from the calendar field values set by the constructor and the time zone "GMT". This is the reason why the second one (calendar2) has the different time (millisecond) value. The behavior may be confusing, but the Calendar and GregorianCalendar have been working in this way, and changing the behavior would cause incompatibility problems for existing applications. ###@###.### 2004-04-06
06-04-2004