JDK-6440854 : (cal) Exception for Gregorian Calendar class created with 3 parameter constructor
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:i18n
  • Affected Version: 5.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux,windows_xp
  • CPU: x86
  • Submitted: 2006-06-20
  • Updated: 2011-02-16
  • Resolved: 2006-07-17
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 JDK 6
5.0u10Fixed 6 b92Fixed
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
Standard Edition (build 1.5.0_07-b03)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Wersja 5.1.2600]

EXTRA RELEVANT SYSTEM CONFIGURATION :
not relevant

A DESCRIPTION OF THE PROBLEM :
When a constructor specifying class fields is used to create a Gregorian Calendar object and lenient flag is set true, after changing a time related field
every call to get(..) method to access Gregorian Calendar fields throws
an exception.

following code will generate exception
    GregorianCalendar gc = new GregorianCalendar(2006,5,16);
    gc.setLenient(false);
    gc.set(GregorianCalendar.HOUR_OF_DAY, 10);
    gc.get(GregorianCalendar.YEAR);

the problem is obviousely in computeTime() method of Gregorian Calendar
and exception is thrown by following check:
	if (!isLenient()) {
	    for (int field = 0; field < FIELD_COUNT; field++) {
		if (!isExternallySet(field)) {
		    continue;
		}
		if (originalFields[field] != internalGet(field)) {
		    // Restore the original field values
		    System.arraycopy(originalFields, 0, fields, 0, fields.length);
		    throw new IllegalArgumentException(getFieldName(field));
		}
	    }
	}

(problem do not exist in java version 1.4.2_04-b05)

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
run following code:
    GregorianCalendar gc = new GregorianCalendar(2006,5,16);
    gc.setLenient(false);
    gc.set(GregorianCalendar.HOUR_OF_DAY, 10);
    gc.get(GregorianCalendar.YEAR); <-Illegal Argument exception


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
get the value of year field of GregorianCalendar
ACTUAL -
Illegal Argument exception

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.IllegalArgumentException: HOUR

	at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2481)

	at java.util.Calendar.updateTime(Calendar.java:2260)

	at java.util.Calendar.complete(Calendar.java:1305)

	at java.util.Calendar.get(Calendar.java:1088)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
    GregorianCalendar gc = new GregorianCalendar(2006,5,16);
    gc.setLenient(false);
    gc.set(GregorianCalendar.HOUR_OF_DAY, 10);
    gc.get(GregorianCalendar.YEAR); <-Illegal Argument exception

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
use a no parameter constructor and field set methods

Release Regression From : 1.4.2_11
The above release value was the last known release where this 
bug was not reproducible. Since then there has been a regression.

Comments
WORK AROUND There are two possible workarounds. 1. Force field calculation by calling get(int). GregorianCalendar gc = new GregorianCalendar(2006,5,16); gc.get(gc.MONTH); // get the value of any field gc.setLenient(false); System.out.println(gc); gc.set(GregorianCalendar.HOUR_OF_DAY, 10); gc.get(GregorianCalendar.YEAR); 2. Call clear() and set(int, int, int) instead of the 3-parameter constructor. GregorianCalendar gc = new GregorianCalendar(); gc.clear(); gc.set(2006, 5, 16); gc.setLenient(false); gc.set(GregorianCalendar.HOUR_OF_DAY, 10); gc.get(GregorianCalendar.YEAR); System.out.println(gc.getTime());
23-06-2006

EVALUATION This is a regression bug caused by the 6178071 fix. When setting the HOUR and AM_PM values in the constructors, these fields should be kept as the COMPUTED state.
21-06-2006