]> granicus.if.org Git - icu/commitdiff
ICU-8596 Fixed the actual maximum week problem.
authorYoshito Umaoka <y.umaoka@gmail.com>
Tue, 5 Jul 2011 22:42:14 +0000 (22:42 +0000)
committerYoshito Umaoka <y.umaoka@gmail.com>
Tue, 5 Jul 2011 22:42:14 +0000 (22:42 +0000)
X-SVN-Rev: 30276

icu4c/source/i18n/calendar.cpp
icu4c/source/test/intltest/calregts.cpp
icu4c/source/test/intltest/calregts.h

index b6a904aff02dd320b2a384097df7affdf3d414e8..72e60849b2e4f768a8f71399c5fb0eb20280d722 100644 (file)
@@ -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);
 
index bc97a5514400d665af6f62c449f6eee6a1321729..e797744675b885d565c5ff336cd6321692bc040a 100644 (file)
@@ -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 */
index d03be6be3bbe27e8ea8dd06533c2d63b2666706e..984a88b55cd3140acdcd6f316397b54f33cc2fd3 100644 (file)
@@ -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) ;