ICU-2792 fix anomalous behavior when adding across a DST boundary

X-SVN-Rev: 11864
This commit is contained in:
Alan Liu 2003-05-09 18:44:54 +00:00
parent 46f091ab0d
commit 914c7c791b
2 changed files with 51 additions and 2 deletions

View file

@ -4,8 +4,8 @@
* others. All Rights Reserved.
*******************************************************************************
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/test/calendar/IBMCalendarTest.java,v $
* $Date: 2003/04/04 17:15:13 $
* $Revision: 1.15 $
* $Date: 2003/05/09 18:44:53 $
* $Revision: 1.16 $
*******************************************************************************
*/
package com.ibm.icu.dev.test.calendar;
@ -411,6 +411,42 @@ public class IBMCalendarTest extends CalendarTest {
}
}
/**
* Make sure that when adding a day, we actually wind up in a
* different day. The DST adjustments we use to keep the hour
* constant across DST changes can backfire and change the day.
*/
public void TestTimeZoneTransitionAdd() {
Locale locale = Locale.US; // could also be CHINA
SimpleDateFormat dateFormat =
new SimpleDateFormat("MM/dd/yyyy HH:mm z", locale);
String tz[] = TimeZone.getAvailableIDs();
for (int z=0; z<tz.length; ++z) {
TimeZone t = TimeZone.getTimeZone(tz[z]);
dateFormat.setTimeZone(t);
Calendar cal = Calendar.getInstance(t, locale);
cal.clear();
// Scan the year 2003, overlapping the edges of the year
cal.set(Calendar.YEAR, 2002);
cal.set(Calendar.MONTH, Calendar.DECEMBER);
cal.set(Calendar.DAY_OF_MONTH, 25);
for (int i=0; i<365+10; ++i) {
Date yesterday = cal.getTime();
int yesterday_day = cal.get(Calendar.DAY_OF_MONTH);
cal.add(Calendar.DAY_OF_MONTH, 1);
if (yesterday_day == cal.get(Calendar.DAY_OF_MONTH)) {
errln(tz[z] + " " +
dateFormat.format(yesterday) + " +1d= " +
dateFormat.format(cal.getTime()));
}
}
}
}
/**
* Miscellaneous tests to increase coverage.
*/

View file

@ -2767,8 +2767,10 @@ public abstract class Calendar implements Serializable, Cloneable {
// operation. If it has changed, then adjust the millis to
// compensate.
int dst = 0;
int hour = 0;
if (keepHourInvariant) {
dst = get(DST_OFFSET);
hour = internalGet(HOUR_OF_DAY);
}
setTimeInMillis(getTimeInMillis() + delta);
@ -2776,7 +2778,18 @@ public abstract class Calendar implements Serializable, Cloneable {
if (keepHourInvariant) {
dst -= get(DST_OFFSET);
if (dst != 0) {
// We have done an hour-invariant adjustment but the
// DST offset has altered. We adjust millis to keep
// the hour constant. In cases such as midnight after
// a DST change which occurs at midnight, there is the
// danger of adjusting into a different day. To avoid
// this we make the adjustment only if it actually
// maintains the hour.
long t = time;
setTimeInMillis(time + dst);
if (get(HOUR_OF_DAY) != hour) {
setTimeInMillis(t);
}
}
}
}