Patch-Source: https://github.com/unicode-org/icu/commit/1b15a4e9db345b67ad284b92801f3fd99fe56e69 -- From 1b15a4e9db345b67ad284b92801f3fd99fe56e69 Mon Sep 17 00:00:00 2001 From: Frank Tang Date: Thu, 29 Jun 2023 14:55:05 -0700 Subject: [PATCH] ICU-22424 Fix Calendar::clear(UCAL_MONTH) Make the calling of clear(UCAL_MONTH or UCAL_ORDINAL_MONTH) clear both fields. --- icu4c/source/i18n/calendar.cpp | 11 +++++++++- icu4c/source/i18n/unicode/calendar.h | 3 ++- icu4c/source/test/intltest/caltest.cpp | 28 ++++++++++++++++++++++++++ icu4c/source/test/intltest/caltest.h | 2 ++ 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/icu4c/source/i18n/calendar.cpp b/icu4c/source/i18n/calendar.cpp index 72d5d10ed5f..d8d544581ea 100644 --- a/i18n/calendar.cpp +++ b/i18n/calendar.cpp @@ -1305,7 +1305,16 @@ Calendar::clear(UCalendarDateFields field) } fFields[field] = 0; fStamp[field] = kUnset; - fIsSet[field] = false; // Remove later + if (field == UCAL_MONTH) { + fFields[UCAL_ORDINAL_MONTH] = 0; + fStamp[UCAL_ORDINAL_MONTH] = kUnset; + fIsSet[UCAL_ORDINAL_MONTH] = false; // Remove later + } + if (field == UCAL_ORDINAL_MONTH) { + fFields[UCAL_MONTH] = 0; + fStamp[UCAL_MONTH] = kUnset; + fIsSet[UCAL_MONTH] = false; // Remove later + } fIsTimeSet = fAreFieldsSet = fAreAllFieldsSet = fAreFieldsVirtuallySet = false; } diff --git a/icu4c/source/i18n/unicode/calendar.h b/icu4c/source/i18n/unicode/calendar.h index aa83866ac9c..26781f8a056 100644 --- a/i18n/unicode/calendar.h +++ b/i18n/unicode/calendar.h @@ -1237,7 +1237,8 @@ class U_I18N_API Calendar : public UObject { /** * Clears the value in the given time field, both making it unset and assigning it a * value of zero. This field value will be determined during the next resolving of - * time into time fields. + * time into time fields. Clearing UCAL_ORDINAL_MONTH or UCAL_MONTH will + * clear both fields. * * @param field The time field to be cleared. * @stable ICU 2.6. diff --git a/icu4c/source/test/intltest/caltest.cpp b/icu4c/source/test/intltest/caltest.cpp index 7518f1123a7..217fc692fed 100644 --- a/test/intltest/caltest.cpp +++ b/test/intltest/caltest.cpp @@ -184,6 +184,7 @@ void CalendarTest::runIndexedTest( int32_t index, UBool exec, const char* &name, TESTCASE_AUTO(TestLimitsOrdinalMonth); TESTCASE_AUTO(TestActualLimitsOrdinalMonth); TESTCASE_AUTO(TestChineseCalendarMonthInSpecialYear); + TESTCASE_AUTO(TestClearMonth); TESTCASE_AUTO_END; } @@ -3887,6 +3888,33 @@ void CalendarTest::TestChineseCalendarMapping() { } } +void CalendarTest::TestClearMonth() { + UErrorCode status = U_ZERO_ERROR; + LocalPointer cal(Calendar::createInstance(Locale::getRoot(), status)); + if (failure(status, "construct Calendar")) return; + cal->set(2023, UCAL_JUNE, 29); + assertEquals("Calendar::get(UCAL_MONTH)", UCAL_JUNE, cal->get(UCAL_MONTH, status)); + if (failure(status, "Calendar::get(UCAL_MONTH)")) return; + cal->clear(UCAL_MONTH); + assertEquals("Calendar::isSet(UCAL_MONTH) after clear(UCAL_MONTH)", false, !!cal->isSet(UCAL_MONTH)); + assertEquals("Calendar::get(UCAL_MONTH after clear(UCAL_MONTH))", UCAL_JANUARY, !!cal->get(UCAL_MONTH, status)); + if (failure(status, "Calendar::get(UCAL_MONTH)")) return; + + cal->set(UCAL_ORDINAL_MONTH, 7); + assertEquals("Calendar::get(UCAL_MONTH) after set(UCAL_ORDINAL_MONTH, 7)", UCAL_AUGUST, cal->get(UCAL_MONTH, status)); + if (failure(status, "Calendar::get(UCAL_MONTH) after set(UCAL_ORDINAL_MONTH, 7)")) return; + assertEquals("Calendar::get(UCAL_ORDINAL_MONTH) after set(UCAL_ORDINAL_MONTH, 7)", 7, cal->get(UCAL_ORDINAL_MONTH, status)); + if (failure(status, "Calendar::get(UCAL_ORDINAL_MONTH) after set(UCAL_ORDINAL_MONTH, 7)")) return; + + cal->clear(UCAL_ORDINAL_MONTH); + assertEquals("Calendar::isSet(UCAL_ORDINAL_MONTH) after clear(UCAL_ORDINAL_MONTH)", false, !!cal->isSet(UCAL_ORDINAL_MONTH)); + assertEquals("Calendar::get(UCAL_MONTH) after clear(UCAL_ORDINAL_MONTH)", UCAL_JANUARY, cal->get(UCAL_MONTH, status)); + if (failure(status, "Calendar::get(UCAL_MONTH) after clear(UCAL_ORDINAL_MONTH)")) return; + assertEquals("Calendar::get(UCAL_ORDINAL_MONTH) after clear(UCAL_ORDINAL_MONTH)", 0, cal->get(UCAL_ORDINAL_MONTH, status)); + if (failure(status, "Calendar::get(UCAL_ORDINAL_MONTH) after clear(UCAL_ORDINAL_MONTH)")) return; + +} + void CalendarTest::TestGregorianCalendarInTemporalLeapYear() { // test from year 1800 to 2500 UErrorCode status = U_ZERO_ERROR; diff --git a/icu4c/source/test/intltest/caltest.h b/icu4c/source/test/intltest/caltest.h index ee062b2e0ed..bc23702dc91 100644 --- a/test/intltest/caltest.h +++ b/test/intltest/caltest.h @@ -56,6 +56,8 @@ class CalendarTest: public CalendarTimeZoneTest { virtual void TestDebug(); + virtual void TestClearMonth(); + public: // package /** * test subroutine used by TestDisambiguation765