| diff --git a/source/i18n/calendar.cpp b/source/i18n/calendar.cpp |
| index 0f5bf522..11bc19a6 100644 |
| --- a/source/i18n/calendar.cpp |
| +++ b/source/i18n/calendar.cpp |
| @@ -639,7 +639,7 @@ static const int32_t kCalendarLimits[UCAL_FIELD_COUNT][4] = { |
| { 0, 0, 59, 59 }, // MINUTE |
| { 0, 0, 59, 59 }, // SECOND |
| { 0, 0, 999, 999 }, // MILLISECOND |
| - {-12*kOneHour, -12*kOneHour, 12*kOneHour, 30*kOneHour }, // ZONE_OFFSET |
| + {-16*kOneHour, -16*kOneHour, 12*kOneHour, 30*kOneHour }, // ZONE_OFFSET |
| { -1*kOneHour, -1*kOneHour, 2*kOneHour, 2*kOneHour }, // DST_OFFSET |
| {/*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1}, // YEAR_WOY |
| { 1, 1, 7, 7 }, // DOW_LOCAL |
| diff --git a/source/test/intltest/calregts.cpp b/source/test/intltest/calregts.cpp |
| index 930f5032..e4420d71 100644 |
| --- a/source/test/intltest/calregts.cpp |
| +++ b/source/test/intltest/calregts.cpp |
| @@ -98,6 +98,7 @@ CalendarRegressionTest::runIndexedTest( int32_t index, UBool exec, const char* & |
| CASE(54,TestWeekOfYear13548); |
| CASE(55,Test13745); |
| CASE(56,TestUTCWrongAMPM22023); |
| + CASE(57,TestAsiaManilaAfterSetGregorianChange22043); |
| default: name = ""; break; |
| } |
| } |
| @@ -3189,6 +3190,40 @@ void CalendarRegressionTest::TestUTCWrongAMPM22023(void) { |
| VerifyGetStayInBound(-1e-15); |
| } |
| |
| +void CalendarRegressionTest::VerifyNoAssertWithSetGregorianChange(const char* timezone) { |
| + UErrorCode status = U_ZERO_ERROR; |
| + std::unique_ptr<Calendar> cal( |
| + Calendar::createInstance( |
| + TimeZone::createTimeZone(UnicodeString(timezone, -1, US_INV)), |
| + Locale::getEnglish(), |
| + status)); |
| + cal->setTime(Calendar::getNow(), status); |
| + |
| + if (cal->getDynamicClassID() == |
| + GregorianCalendar::getStaticClassID()) { |
| + GregorianCalendar* gc = |
| + static_cast<GregorianCalendar*>(cal.get()); |
| + // The beginning of ECMAScript time, namely -(2**53) |
| + const double start_of_time = -9007199254740992; |
| + gc->setGregorianChange(start_of_time, status); |
| + } |
| + cal->get(UCAL_YEAR, status); |
| +} |
| + |
| +void CalendarRegressionTest::TestAsiaManilaAfterSetGregorianChange22043(void) { |
| + VerifyNoAssertWithSetGregorianChange("Asia/Malina"); |
| + UErrorCode status = U_ZERO_ERROR; |
| + std::unique_ptr<StringEnumeration> ids(TimeZone::createEnumeration(status)); |
| + if (U_FAILURE(status)) { |
| + errln("TimeZone::createEnumeration failed"); |
| + return; |
| + } |
| + const char* id; |
| + while ((id = ids->next(nullptr, status)) != nullptr && U_SUCCESS(status)) { |
| + VerifyNoAssertWithSetGregorianChange(id); |
| + } |
| +} |
| + |
| void CalendarRegressionTest::TestWeekOfYear13548(void) { |
| int32_t year = 2000; |
| UErrorCode status = U_ZERO_ERROR; |
| diff --git a/source/test/intltest/calregts.h b/source/test/intltest/calregts.h |
| index 9581eac2..da815fb4 100644 |
| --- a/source/test/intltest/calregts.h |
| +++ b/source/test/intltest/calregts.h |
| @@ -82,6 +82,7 @@ public: |
| void TestIslamicCalOverflow(void); |
| void TestWeekOfYear13548(void); |
| void TestUTCWrongAMPM22023(void); |
| + void TestAsiaManilaAfterSetGregorianChange22043(void); |
| |
| void Test13745(void); |
| |
| @@ -89,6 +90,7 @@ public: |
| void dowTest(UBool lenient) ; |
| |
| void VerifyGetStayInBound(double test_value); |
| + void VerifyNoAssertWithSetGregorianChange(const char* timezone); |
| |
| static UDate getAssociatedDate(UDate d, UErrorCode& status); |
| static UDate makeDate(int32_t y, int32_t m = 0, int32_t d = 0, int32_t hr = 0, int32_t min = 0, int32_t sec = 0); |