blob: f7ef4169dd475111e8b9e82c2b88bbc76bd27b05 [file] [log] [blame]
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);