From 515788594c821e2bf932732bb7a6da525277f2ee Mon Sep 17 00:00:00 2001 From: Yoshito Umaoka <y.umaoka@gmail.com> Date: Tue, 5 Jul 2011 22:42:14 +0000 Subject: [PATCH] ICU-8596 Fixed the actual maximum week problem. X-SVN-Rev: 30276 --- icu4c/source/i18n/calendar.cpp | 7 +++- icu4c/source/test/intltest/calregts.cpp | 44 +++++++++++++++++++++++++ icu4c/source/test/intltest/calregts.h | 1 + 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/icu4c/source/i18n/calendar.cpp b/icu4c/source/i18n/calendar.cpp index b6a904aff02..72e60849b2e 100644 --- a/icu4c/source/i18n/calendar.cpp +++ b/icu4c/source/i18n/calendar.cpp @@ -3079,7 +3079,7 @@ Calendar::getActualMaximum(UCalendarDateFields field, UErrorCode& status) const if(U_FAILURE(status)) return 0; Calendar *cal = clone(); if(!cal) { status = U_MEMORY_ALLOCATION_ERROR; return 0; } - cal->setLenient(TRUE); + cal->setLenient(TRUE); cal->prepareGetActual(field,FALSE,status); result = handleGetYearLength(cal->get(UCAL_EXTENDED_YEAR, status)); delete cal; @@ -3201,6 +3201,11 @@ int32_t Calendar::getActualHelper(UCalendarDateFields field, int32_t startValue, if(U_FAILURE(status)) return startValue; Calendar *work = clone(); if(!work) { status = U_MEMORY_ALLOCATION_ERROR; return startValue; } + + // need to resolve time here, otherwise, fields set for actual limit + // may cause conflict with fields previously set (but not yet resolved). + work->complete(status); + work->setLenient(TRUE); work->prepareGetActual(field, delta < 0, status); diff --git a/icu4c/source/test/intltest/calregts.cpp b/icu4c/source/test/intltest/calregts.cpp index bc97a551440..e797744675b 100644 --- a/icu4c/source/test/intltest/calregts.cpp +++ b/icu4c/source/test/intltest/calregts.cpp @@ -84,6 +84,7 @@ CalendarRegressionTest::runIndexedTest( int32_t index, UBool exec, const char* & CASE(45,TestT5555); CASE(46,TestT6745); CASE(47,TestT8057); + CASE(48,TestT8596); default: name = ""; break; } } @@ -2811,4 +2812,47 @@ void CalendarRegressionTest::TestT8057(void) { delete cal; } +// Test case for ticket#8596. +// Setting an year followed by getActualMaximum(Calendar.WEEK_OF_YEAR) +// may result wrong maximum week. +void CalendarRegressionTest::TestT8596(void) { + UErrorCode status = U_ZERO_ERROR; + GregorianCalendar *gc = new GregorianCalendar(*TimeZone::getGMT(), status); + + if (U_FAILURE(status)) { + dataerrln("Error creating Calendar: %s", u_errorName(status)); + delete gc; + return; + } + + gc->setFirstDayOfWeek(UCAL_MONDAY); + gc->setMinimalDaysInFirstWeek(4); + + // Force the calender to resolve the fields once. + // The maximum week number in 2011 is 52. + gc->set(UCAL_YEAR, 2011); + gc->get(UCAL_YEAR, status); + + // Set a date in year 2009, but not calling get to resolve + // the calendar's internal field yet. + gc->set(2009, UCAL_JULY, 1); + + // Then call getActuamMaximum for week of year. + // #8596 was caused by conflict between year set + // above and internal work calendar field resolution. + int32_t maxWeeks = gc->getActualMaximum(UCAL_WEEK_OF_YEAR, status); + + if (U_FAILURE(status)) { + errln("Error calendar calculation: %s", u_errorName(status)); + delete gc; + return; + } + + if (maxWeeks != 53) { + errln((UnicodeString)"FAIL: Max week in 2009 in ISO calendar is 53, but got " + maxWeeks); + } + + delete gc; +} + #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/icu4c/source/test/intltest/calregts.h b/icu4c/source/test/intltest/calregts.h index d03be6be3bb..984a88b55cd 100644 --- a/icu4c/source/test/intltest/calregts.h +++ b/icu4c/source/test/intltest/calregts.h @@ -72,6 +72,7 @@ public: void TestWeekShift(void); void TestTimeZoneTransitionAdd(void); void TestDeprecates(void); + void TestT8596(void); void printdate(GregorianCalendar *cal, const char *string); void dowTest(UBool lenient) ; -- 2.40.0