ICU-9452 Fixed calendar addition issue with the Samoa Dec 2011 24 hour transition (ICU4J)

X-SVN-Rev: 32142
This commit is contained in:
Yoshito Umaoka 2012-08-09 21:37:41 +00:00
parent bc8ee5cca6
commit 091464430b
2 changed files with 46 additions and 4 deletions

View file

@ -3265,10 +3265,18 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
// 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 + prevOffset - newOffset);
if (get(HOUR_OF_DAY) != hour) {
setTimeInMillis(t);
// When the difference of the previous UTC offset and
// the new UTC offset exceeds 1 full day, we do not want
// to roll over/back the date. For now, this only happens
// in Samoa (Pacific/Apia) on Dec 30, 2011. See ticket:9452.
long adjAmount = (prevOffset - newOffset) % ONE_DAY;
if (adjAmount != 0) {
long t = time;
setTimeInMillis(time + adjAmount);
if (get(HOUR_OF_DAY) != hour) {
setTimeInMillis(t);
}
}
}
}

View file

@ -2261,6 +2261,40 @@ public class CalendarRegression extends com.ibm.icu.dev.test.TestFmwk {
logln("Pass: rolled calendar is " + cal1.getTime());
}
}
/**
* Test case for ticket 9452
* Calendar addition fall onto the missing date - 2011-12-30 in Samoa
*/
public void TestT9452() {
TimeZone samoaTZ = TimeZone.getTimeZone("Pacific/Apia");
GregorianCalendar cal = new GregorianCalendar(samoaTZ);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZZ");
sdf.setTimeZone(samoaTZ);
// Set date to 2011-12-29 00:00
cal.clear();
cal.set(2011, Calendar.DECEMBER, 29, 0, 0, 0);
Date d = cal.getTime();
String dstr = sdf.format(d);
logln("Initial date: " + dstr);
// Add 1 day
cal.add(Calendar.DATE, 1);
d = cal.getTime();
dstr = sdf.format(d);
logln("+1 day: " + dstr);
assertEquals("Add 1 day", "2011-12-31T00:00:00+14:00", dstr);
// Subtract 1 day
cal.add(Calendar.DATE, -1);
d = cal.getTime();
dstr = sdf.format(d);
logln("-1 day: " + dstr);
assertEquals("Subtract 1 day", "2011-12-29T00:00:00-10:00", dstr);
}
}
//eof