-
Enhancement
-
Resolution: Won't Fix
-
P5
-
None
-
1.3.0
-
None
-
sparc
-
solaris_2.5.1
Name: clC74495 Date: 03/22/2000
The TimeZone method getOffset exists in two flavors. One is an old
public method. The other is a newer package-private method that
java.util uses internally.
Recently, the old public getOffset was fixed to handle leap years. Unfortunately, this fix was done incorrectly. Here is the fix present in recent 1.3 RC code:
int monthLength, prevMonthLength;
if ((era == GregorianCalendar.AD) && internalCal.isLeapYear(year)) {
monthLength = staticLeapMonthLength[month];
prevMonthLength = (month > 1) ? staticLeapMonthLength[month - 1] : 31;
} else {
monthLength = staticMonthLength[month];
prevMonthLength = (month > 1) ? staticMonthLength[month - 1] : 31;
}
This check for era == AD is inconsistent with the way GregorianCalendar works. GregorianCalendar is a proleptic calendar, and as such, it extends leap years back into the BC era. See Bug 4125892 for more discussion of this.
The fix to this is simple. Replace the check for era == AD with the following:
int y = year;
if (era == GregorianCalendar.BC) {
y = 1 - y;
}
if (internalCal.isLeapYear(y)) {
... // as before
This code is better because, no matter what, it is consistent with GregorianCalendar, since it defers its determination of what a leap year is entirely to GC.
This may seem to be an esoteric problem, but it was actually discovered while trying to subclass Calendar. Since the package private getOffset method is not available outside the java.util package, I was forced to use the public getOffset method. This works fine, except for BC years, at which point certain ordinary, legal Calendar operations cause an IllegalArgumentException to be thrown, because of this bug. Reproducing this is easy: Derive a subclass of Calendar that uses the public getOffset, then execute the following code on it:
cal.clear();
cal.set(Calendar.ERA, GregorianCalendar.BC);
cal.set(Calendar.YEAR, 81);
cal.set(Calendar.MONTH, Calendar.FEBRUARY);
cal.set(Calendar.DATE, 28);
cal.add(Calendar.DATE, 1);
The call to add() will throw an exception.
(Review ID: 102696)
======================================================================
- relates to
-
JDK-4761696 (tz) Rewrite SimpleTimeZone to support correct DST transitions
-
- Resolved
-