-
Bug
-
Resolution: Won't Fix
-
P4
-
None
-
1.2.0, 1.4.0, 5.0
-
generic, x86
-
generic, windows_2000, windows_xp
Name: bb33257 Date: 02/05/99
There is a problem in Calendar in JDK 1.2. Subclasses that
were written for JDK 1.1 don't work anymore. Consider a
subclass that has to work with both 1.1.x and 1.2. It can't
use the stamp array in my computeTime method. Instead, it
has to rely on calling isSet().
Consider the following calls:
// Now find the # of days in the month
c.roll(Calendar.DATE, false);
daysInMonth = c.get(Calendar.DATE);
When roll is called, it ends up calling set on the DATE
field, which has the side effect of setting areFieldsSet and
isTimeSet to false. It also sets isSet[DATE] to true and
updates stamp[DATE].
If c is a Gregorian calendar, then it works properly.
Here's what happens:
1. The roll method calls complete, which calls computeFields.
2. After the fields values are set,
GregorianCalendar.computeFields sets each element in the
stamp array to INTERNALLY_SET.
3. The get method immediately calls complete, which notices
that isTimeSet is false and calls updateTime, which in turn
calls computeTime.
4. That method uses the stamp array to decide which fields
it should use to compute the time. It doesn't look at the
isSet array at all. It properly updates the time based on
the relevant fields.
5. Next, complete calls computeFields.
6. Finally, get returns fields[DATE].
In contrast, if c is a JDK 1.1-compatible subclass, this is
what happens:
1. same thing: roll ends up calling computeFields.
2. Nothing (!): computeFields method doesn't have access
to the stamp array.
3. same thing: get ends up calling computeTime.
4. computeTime method calls isSet() to decide which
combination of fields to use, much like the Gregorian
calendar used to do.
5. In 1.2, isSet() returns (stamp[field] != UNSET). This is
almost always false, because computeFields wasn't able to
update the stamp array.
6. The calendar thinks there aren't enough fields set to
compute the time, so it throws an exception. Boom.
To restate the requirements for 1.2 and later, we want the
following:
1. Subclasses under 1.1 should work under 1.2.
This means isSet() must work, in particular, it must read
the isSet[] array, since subclasses may modify that array
directly.
2. Subclasses under 1.2 should work.
If a subclass sets up the fields, it must be able to make
isSet() do the right thing.
3. GregorianCalendar and other subclasses within java.text
must work.
For this to be true, isSet() has to read the time stamp.
So I propose:
1. Make isSet() read the isSet[] array.
2. Make Calendar.isSet() non-final, and for GregorianCalendar,
override it to read the time stamp.
(Review ID: 53793)
======================================================================
There is a problem in Calendar in JDK 1.2. Subclasses that
were written for JDK 1.1 don't work anymore. Consider a
subclass that has to work with both 1.1.x and 1.2. It can't
use the stamp array in my computeTime method. Instead, it
has to rely on calling isSet().
Consider the following calls:
// Now find the # of days in the month
c.roll(Calendar.DATE, false);
daysInMonth = c.get(Calendar.DATE);
When roll is called, it ends up calling set on the DATE
field, which has the side effect of setting areFieldsSet and
isTimeSet to false. It also sets isSet[DATE] to true and
updates stamp[DATE].
If c is a Gregorian calendar, then it works properly.
Here's what happens:
1. The roll method calls complete, which calls computeFields.
2. After the fields values are set,
GregorianCalendar.computeFields sets each element in the
stamp array to INTERNALLY_SET.
3. The get method immediately calls complete, which notices
that isTimeSet is false and calls updateTime, which in turn
calls computeTime.
4. That method uses the stamp array to decide which fields
it should use to compute the time. It doesn't look at the
isSet array at all. It properly updates the time based on
the relevant fields.
5. Next, complete calls computeFields.
6. Finally, get returns fields[DATE].
In contrast, if c is a JDK 1.1-compatible subclass, this is
what happens:
1. same thing: roll ends up calling computeFields.
2. Nothing (!): computeFields method doesn't have access
to the stamp array.
3. same thing: get ends up calling computeTime.
4. computeTime method calls isSet() to decide which
combination of fields to use, much like the Gregorian
calendar used to do.
5. In 1.2, isSet() returns (stamp[field] != UNSET). This is
almost always false, because computeFields wasn't able to
update the stamp array.
6. The calendar thinks there aren't enough fields set to
compute the time, so it throws an exception. Boom.
To restate the requirements for 1.2 and later, we want the
following:
1. Subclasses under 1.1 should work under 1.2.
This means isSet() must work, in particular, it must read
the isSet[] array, since subclasses may modify that array
directly.
2. Subclasses under 1.2 should work.
If a subclass sets up the fields, it must be able to make
isSet() do the right thing.
3. GregorianCalendar and other subclasses within java.text
must work.
For this to be true, isSet() has to read the time stamp.
So I propose:
1. Make isSet() read the isSet[] array.
2. Make Calendar.isSet() non-final, and for GregorianCalendar,
override it to read the time stamp.
(Review ID: 53793)
======================================================================
- duplicates
-
JDK-6348938 (cal) Need Read-access to the stamp data member of the Calendar class
- Closed
-
JDK-4638858 Access to stamp data member in Calendar class
- Closed
- relates to
-
JDK-4112923 API: Calendar field time stamps
- Closed
-
JDK-4219675 RFE: Calendar is too complicated
- Closed