ICU-9452 Fixed calendar add issue with the Samoa Dec 2011 24 hour transition.

X-SVN-Rev: 32141
This commit is contained in:
Yoshito Umaoka 2012-08-09 21:29:53 +00:00
parent ad0573b824
commit bc8ee5cca6
3 changed files with 58 additions and 4 deletions

View file

@ -2005,10 +2005,19 @@ void Calendar::add(UCalendarDateFields field, int32_t amount, UErrorCode& status
// danger of adjusting into a different day. To avoid
// this we make the adjustment only if it actually
// maintains the hour.
double t = internalGetTime();
setTimeInMillis(t + prevOffset - newOffset, status);
if (get(UCAL_HOUR_OF_DAY, status) != hour) {
setTimeInMillis(t, status);
// 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.
int32_t adjAmount = prevOffset - newOffset;
adjAmount = adjAmount >= 0 ? adjAmount % (int32_t)kOneDay : -(-adjAmount % (int32_t)kOneDay);
if (adjAmount != 0) {
double t = internalGetTime();
setTimeInMillis(t + adjAmount, status);
if (get(UCAL_HOUR_OF_DAY, status) != hour) {
setTimeInMillis(t, status);
}
}
}
}

View file

@ -87,6 +87,7 @@ CalendarRegressionTest::runIndexedTest( int32_t index, UBool exec, const char* &
CASE(47,TestT8057);
CASE(48,TestT8596);
CASE(49,Test9019);
CASE(50,TestT9452);
default: name = ""; break;
}
}
@ -2898,4 +2899,47 @@ void CalendarRegressionTest::TestT8596(void) {
delete gc;
}
// Test case for ticket 9452
// Calendar addition fall onto the missing date - 2011-12-30 in Samoa
void CalendarRegressionTest::TestT9452(void) {
UErrorCode status = U_ZERO_ERROR;
GregorianCalendar cal(TimeZone::createTimeZone("Pacific/Apia"), status);
failure(status, "initializing GregorianCalendar");
SimpleDateFormat sdf(UnicodeString("y-MM-dd'T'HH:mm:ssZZZZZ"), status);
failure(status, "initializing SimpleDateFormat");
sdf.setCalendar(cal);
UnicodeString dstr;
// Set date to 2011-12-29 00:00
cal.clear();
cal.set(2011, UCAL_DECEMBER, 29, 0, 0, 0);
UDate d = cal.getTime(status);
failure(status, "getTime for initial date");
sdf.format(d, dstr);
logln(UnicodeString("Initial date: ") + dstr);
// Add 1 day
cal.add(UCAL_DATE, 1, status);
failure(status, "add 1 day");
d = cal.getTime(status);
failure(status, "getTime after +1 day");
dstr.remove();
sdf.format(d, dstr);
logln(UnicodeString("+1 day: ") + dstr);
assertEquals("Add 1 day", UnicodeString("2011-12-31T00:00:00+14:00"), dstr);
// Subtract 1 day
cal.add(UCAL_DATE, -1, status);
failure(status, "subtract 1 day");
d = cal.getTime(status);
failure(status, "getTime after -1 day");
dstr.remove();
sdf.format(d, dstr);
logln(UnicodeString("-1 day: ") + dstr);
assertEquals("Subtract 1 day", UnicodeString("2011-12-29T00:00:00-10:00"), dstr);
}
#endif /* #if !UCONFIG_NO_FORMATTING */

View file

@ -74,6 +74,7 @@ public:
void TestDeprecates(void);
void TestT8596(void);
void Test9019(void);
void TestT9452(void);
void printdate(GregorianCalendar *cal, const char *string);
void dowTest(UBool lenient) ;