-
Bug
-
Resolution: Fixed
-
P4
-
1.2.2, 1.3.0
-
beta
-
generic
-
generic
Name: skT88420 Date: 01/04/2000
java version "1.2.2"
Classic VM (build JDK-1.2.2-001, native threads, nojit)
U implemented an optimisation for the dst correction, but I suspect it's wrong.
At least it will never optimize, because delta cannot be 0, because there is
another optimisation that
if (amount == 0) return; // Do nothing!
and delta is amount. Therefore
if (delta != 0) setTimeInMillis(time + dst);
will always call setTimeInMillis, I suppose u want to check against dst != 0!
Thanks
Patrick
Here I attach the method with the Patch:
/**
* Overrides Calendar
* Date Arithmetic function.
* Adds the specified (signed) amount of time to the given time field,
* based on the calendar's rules.
* @param field the time field.
* @param amount the amount of date or time to be added to the field.
* @exception IllegalArgumentException if an unknown field is given.
*/
public void add(int field, int amount) {
if (amount == 0) return; // Do nothing!
complete();
if (field == YEAR) {
int year = this.internalGet(YEAR);
if (this.internalGetEra() == AD) {
year += amount;
if (year > 0)
this.set(YEAR, year);
else { // year <= 0
this.set(YEAR, 1 - year);
// if year == 0, you get 1 BC
this.set(ERA, BC);
}
}
else { // era == BC
year -= amount;
if (year > 0)
this.set(YEAR, year);
else { // year <= 0
this.set(YEAR, 1 - year);
// if year == 0, you get 1 AD
this.set(ERA, AD);
}
}
pinDayOfMonth();
}
else if (field == MONTH) {
int month = this.internalGet(MONTH) + amount;
if (month >= 0) {
set(YEAR, internalGet(YEAR) + (month / 12));
set(MONTH, (int) (month % 12));
}
else { // month < 0
set(YEAR, internalGet(YEAR) + ((month + 1) / 12) - 1);
month %= 12;
if (month < 0) month += 12;
set(MONTH, JANUARY + month);
}
pinDayOfMonth();
}
else if (field == ERA) {
int era = internalGet(ERA) + amount;
if (era < 0) era = 0;
if (era > 1) era = 1;
set(ERA, era);
}
else {
// We handle most fields here. The algorithm is to add a computed amount
// of millis to the current millis. The only wrinkle is with DST -- if
// the result of the add operation is to move from DST to Standard, or vice
// versa, we need to adjust by an hour forward or back, respectively.
// Otherwise you get weird effects in which the hour seems to shift when
// you add to the DAY_OF_MONTH field, for instance.
// We only adjust the DST for fields larger than an hour. For fields
// smaller than an hour, we cannot adjust for DST without causing problems.
// for instance, if you add one hour to April 5, 1998, 1:00 AM, in PST,
// the time becomes "2:00 AM PDT" (an illegal value), but then the adjustment
// sees the change and compensates by subtracting an hour. As a result the
// time doesn't advance at all.
long delta = amount;
boolean adjustDST = true;
switch (field) {
case WEEK_OF_YEAR:
case WEEK_OF_MONTH:
case DAY_OF_WEEK_IN_MONTH:
delta *= 7 * 24 * 60 * 60 * 1000; // 7 days
break;
case AM_PM:
delta *= 12 * 60 * 60 * 1000; // 12 hrs
break;
case DATE: // synonym of DAY_OF_MONTH
case DAY_OF_YEAR:
case DAY_OF_WEEK:
delta *= 24 * 60 * 60 * 1000; // 1 day
break;
case HOUR_OF_DAY:
case HOUR:
delta *= 60 * 60 * 1000; // 1 hour
adjustDST = false;
break;
case MINUTE:
delta *= 60 * 1000; // 1 minute
adjustDST = false;
break;
case SECOND:
delta *= 1000; // 1 second
adjustDST = false;
break;
case MILLISECOND:
adjustDST = false;
break;
case ZONE_OFFSET:
case DST_OFFSET:
default:
throw new IllegalArgumentException();
}
// Save the current DST state.
long dst = 0;
if (adjustDST) dst = internalGet(DST_OFFSET);
setTimeInMillis(time + delta); // Automatically computes fields if necessary
if (adjustDST) {
// Now do the DST adjustment alluded to above.
// Only call setTimeInMillis if necessary, because it's an expensive call.
dst -= internalGet(DST_OFFSET);
// Patch: Optimisation is probably wrong, delta is amount and cannot be 0,suppose u want to
// check against dst != 0!
// if (delta != 0) setTimeInMillis(time + dst);
if (dst != 0) setTimeInMillis(time + dst);
//////////////////////////////////////////////////////////////
}
}
}
(Review ID: 99410)
======================================================================
- duplicates
-
JDK-4326867 GregorianCalendar.add does extra setTimeInMillis call for field UOM < MONTH.
-
- Closed
-