JDK-4965624 : GregorianCalendar.isLeapYear(1000) returns incorrect value
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:i18n
  • Affected Version: 5.0
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: solaris_2.6
  • CPU: sparc
  • Submitted: 2003-12-09
  • Updated: 2004-09-01
  • Resolved: 2004-03-16
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
5.0 b43Fixed
Related Reports
Relates :  
Description

Name: auR10023			Date: 12/09/2003


Filed By      : SPB JCK team (###@###.###)
JDK           : java full version "1.5.0-beta-b30"
JCK           : 1.5
Platform[s]   : Solaris
switch/Mode   : 
JCK test owner : http://javaweb.eng/jct/sqe/JCK-tck/usr/owners.jto
Failing Test [s] :
    api/java_util/GregorianCalendar/index.html#SetGet[GregorianCalendar0026]


Problem description
===================
java.util.GregorianCalendar.isLeapYear(1000) returns false with GMT offsets >= 10.
Year 1000 is leap in both julian and gregorian calendars so this method should return true.


    
Minimized test:
===============
------- Test.java -------
import java.util.*;

public class Test {
    public static void main (String [] args) {
        String tz [] = {"GMT+8", "GMT+9", "GMT+10", "GMT+11", "GMT+12"};
        for (int i = 0; i < tz.length; i++) { 
            GregorianCalendar calendar = 
                new GregorianCalendar(TimeZone.getTimeZone(tz[i]));
            calendar.set(1001, 0, 1);
            calendar.setGregorianChange(calendar.getTime());
            System.out.println("calendar = GregorianCalendar(" +
                               "TimeZone.getTimeZone(\"" + 
                               tz[i] + "\"))");
            System.out.println("calendar.isLeapYear(1000) = " + 
                               calendar.isLeapYear(1000));
            System.out.println();
        }
    }
}

------- end-of-Test.java -------

Minimized test output:
======================
calendar = GregorianCalendar(TimeZone.getTimeZone("GMT+8"))
calendar.isLeapYear(1000) = true

calendar = GregorianCalendar(TimeZone.getTimeZone("GMT+9"))
calendar.isLeapYear(1000) = true

calendar = GregorianCalendar(TimeZone.getTimeZone("GMT+10"))
calendar.isLeapYear(1000) = false

calendar = GregorianCalendar(TimeZone.getTimeZone("GMT+11"))
calendar.isLeapYear(1000) = false

calendar = GregorianCalendar(TimeZone.getTimeZone("GMT+12"))
calendar.isLeapYear(1000) = false


JCK test source location:
==========================
/java/re/jck/1.5/promoted/latest/JCK-runtime-15/tests
    
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: tiger-beta2 FIXED IN: tiger-beta2 INTEGRATED IN: tiger-b43 tiger-beta2 VERIFIED IN: tiger-b63
13-09-2004

EVALUATION The problem is not repro. $ java -showversion Test java version "1.5.0-beta" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta-b30) Java HotSpot(TM) Client VM (build 1.5.0-beta-b30, mixed mode) calendar = GregorianCalendar(TimeZone.getTimeZone("GMT+8")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT+9")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT+10")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT+11")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT+12")) calendar.isLeapYear(1000) = true The symptom might be related to the platform time zone where the test program ran. I tried several time zones, but couldn't reproduce the problem. Which platform time zone was used to run the test program? By the way, year 1000 is not a leap year in Gregorian. ###@###.### 2003-12-10 Name: auR10023 Date: 12/10/2003 Yes, you are right. The behavior of this method depends on system time zone. I've extended my test by additional test values so (I think) it can help in your case. By the way, why year 1000 is not leap in gregorian calendar?(it isn't divided by 400 and it is divided by 4). Or may be these rules could not be applied for some reason. Test.java ------------------------------------------------------------------------------ import java.util.*; public class Test { public static void main (String [] args) { String tz [] = {"GMT-12", "GMT-11", "GMT-10", "GMT-9", "GMT-8", "GMT-7", "GMT-6", "GMT-5", "GMT-4", "GMT-3", "GMT-2", "GMT-1", "GMT", "GMT+1", "GMT+2", "GMT+3", "GMT+4", "GMT+5", "GMT+6", "GMT+7", "GMT+8", "GMT+9", "GMT+10", "GMT+11", "GMT+12"}; for (int i = 0; i < tz.length; i++) { GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone(tz[i])); calendar.set(1001, 0, 1); calendar.setGregorianChange(calendar.getTime()); System.out.println("calendar = GregorianCalendar(" + "TimeZone.getTimeZone(\"" + tz[i] + "\"))"); System.out.println("calendar.isLeapYear(1000) = " + calendar.isLeapYear(1000)); System.out.println(); } } } ------------------------------------------------------------------------------ #echo $TZ Russia/Moscow #java -cp . Test calendar = GregorianCalendar(TimeZone.getTimeZone("GMT-12")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT-11")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT-10")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT-9")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT-8")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT-7")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT-6")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT-5")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT-4")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT-3")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT-2")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT-1")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT+1")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT+2")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT+3")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT+4")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT+5")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT+6")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT+7")) calendar.isLeapYear(1000) = true calendar = GregorianCalendar(TimeZone.getTimeZone("GMT+8")) calendar.isLeapYear(1000) = false calendar = GregorianCalendar(TimeZone.getTimeZone("GMT+9")) calendar.isLeapYear(1000) = false calendar = GregorianCalendar(TimeZone.getTimeZone("GMT+10")) calendar.isLeapYear(1000) = false calendar = GregorianCalendar(TimeZone.getTimeZone("GMT+11")) calendar.isLeapYear(1000) = false calendar = GregorianCalendar(TimeZone.getTimeZone("GMT+12")) calendar.isLeapYear(1000) = false ====================================================================== I modified the test program to use all the TimeZones available on Tiger. import java.util.*; public class Test { public static void main (String [] args) { String tz [] = {"GMT-12", "GMT-11", "GMT-10", "GMT-9", "GMT-8", "GMT-7", "GMT-6", "GMT-5", "GMT-4", "GMT-3", "GMT-2", "GMT-1", "GMT", "GMT+1", "GMT+2", "GMT+3", "GMT+4", "GMT+5", "GMT+6", "GMT+7", "GMT+8", "GMT+9", "GMT+10", "GMT+11", "GMT+12"}; String[] allTimeZones = TimeZone.getAvailableIDs(); for (int x = 0; x < allTimeZones.length; x++) { TimeZone zone = TimeZone.getTimeZone(allTimeZones[x]); TimeZone.setDefault(zone); for (int i = 0; i < tz.length; i++) { GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone(tz[i])); calendar.set(1001, 0, 1); calendar.setGregorianChange(calendar.getTime()); if (!calendar.isLeapYear(1000)) { System.out.println("default zone = " + zone); System.out.println("calendar = GregorianCalendar(" + "TimeZone.getTimeZone(\"" + tz[i] + "\"))"); System.out.println("calendar.isLeapYear(1000) = " + calendar.isLeapYear(1000)); System.out.println(); } } } } } -- It's still not reproducible. $ java -showversion Test java version "1.5.0-beta" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta-b32) Java HotSpot(TM) Client VM (build 1.5.0-beta-b32, mixed mode) I'm closing this bug report as not repro. ###@###.### 2003-12-26 ====================================================================== The last demo test is reproducible only in the following time frame: from 15:01 till 02:59. Time zone we use is Europe/Moscow. Hope it will make the test to fail now on your side. Please try to re-run the demo test. ###@###.### 2004-02-25 ====================================================================== The cause is that isLeapYear doesn't handle the Gregorian change date correctly for determining whether the given year is Julian or Gregorian. Before Tiger, that was worse. See Comments for the test case. ###@###.### 2004-02-27 Another problem is that the given Gregorian change has to be interpreted as a local date, while the time is given as GMT time. ###@###.### 2004-03-01
27-02-2004