mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-07 22:44:49 +00:00
ICU-2792 fix anomalous behavior when adding across a DST boundary
X-SVN-Rev: 11864
This commit is contained in:
parent
46f091ab0d
commit
914c7c791b
2 changed files with 51 additions and 2 deletions
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue