ICU-22041 Fix "Africa/Casablanca" show strange LONG displayName
See #2096
diff --git a/icu4c/source/i18n/olsontz.cpp b/icu4c/source/i18n/olsontz.cpp
index cae471a..0f06db5 100644
--- a/icu4c/source/i18n/olsontz.cpp
+++ b/icu4c/source/i18n/olsontz.cpp
@@ -430,8 +430,7 @@
int32_t OlsonTimeZone::getRawOffset() const {
UErrorCode ec = U_ZERO_ERROR;
int32_t raw, dst;
- getOffset((double) uprv_getUTCtime() * U_MILLIS_PER_SECOND,
- FALSE, raw, dst, ec);
+ getOffset(uprv_getUTCtime(), FALSE, raw, dst, ec);
return raw;
}
diff --git a/icu4c/source/i18n/rbtz.cpp b/icu4c/source/i18n/rbtz.cpp
index 495d831..7eba471 100644
--- a/icu4c/source/i18n/rbtz.cpp
+++ b/icu4c/source/i18n/rbtz.cpp
@@ -479,8 +479,7 @@
// as of current time.
UErrorCode status = U_ZERO_ERROR;
int32_t raw, dst;
- getOffset(uprv_getUTCtime() * U_MILLIS_PER_SECOND,
- FALSE, raw, dst, status);
+ getOffset(uprv_getUTCtime(), FALSE, raw, dst, status);
return raw;
}
@@ -490,7 +489,7 @@
// daylight saving time is used as of now or
// after the next transition.
UErrorCode status = U_ZERO_ERROR;
- UDate now = uprv_getUTCtime() * U_MILLIS_PER_SECOND;
+ UDate now = uprv_getUTCtime();
int32_t raw, dst;
getOffset(now, FALSE, raw, dst, status);
if (dst != 0) {
diff --git a/icu4c/source/test/intltest/tztest.cpp b/icu4c/source/test/intltest/tztest.cpp
index 5ae9ae7..d949276 100644
--- a/icu4c/source/test/intltest/tztest.cpp
+++ b/icu4c/source/test/intltest/tztest.cpp
@@ -76,6 +76,8 @@
TESTCASE_AUTO(TestGetGMT);
TESTCASE_AUTO(TestGetWindowsID);
TESTCASE_AUTO(TestGetIDForWindowsID);
+ TESTCASE_AUTO(TestCasablancaNameAndOffset22041);
+ TESTCASE_AUTO(TestRawOffsetAndOffsetConsistency22041);
TESTCASE_AUTO_END;
}
@@ -2544,4 +2546,41 @@
}
}
+void TimeZoneTest::TestCasablancaNameAndOffset22041(void) {
+ std::unique_ptr<TimeZone> zone(TimeZone::createTimeZone("Africa/Casablanca"));
+ UnicodeString standardName, summerName;
+ zone->getDisplayName(false, TimeZone::LONG, Locale::getEnglish(), standardName);
+ zone->getDisplayName(true, TimeZone::LONG, Locale::getEnglish(), summerName);
+ int32_t raw, dst;
+ UErrorCode status = U_ZERO_ERROR;
+ zone->getOffset(Calendar::getNow(), false, raw, dst, status);
+ assertEquals(u"TimeZone name for Africa/Casablanca should not contain '+02' since it is located in UTC, but got "
+ + standardName, -1, standardName.indexOf("+02"));
+ assertEquals(u"TimeZone name for Africa/Casablanca should not contain '+02' since it is located in UTC, but got "
+ + summerName, -1, summerName.indexOf("+02"));
+ assertEquals("getRawOffset() and the raw from getOffset(now, false, raw, dst, status) should not be different but got",
+ zone->getRawOffset(), raw);
+}
+
+void TimeZoneTest::TestRawOffsetAndOffsetConsistency22041(void) {
+ UErrorCode status = U_ZERO_ERROR;
+ LocalPointer<StringEnumeration> s(TimeZone::createEnumeration(status));
+ if (U_FAILURE(status)) {
+ dataerrln("Unable to create TimeZone enumeration");
+ return;
+ }
+ const char* tz;
+ UDate now = Calendar::getNow();
+ while ((tz = s->next(nullptr, status)) != nullptr && U_SUCCESS(status)) {
+ std::unique_ptr<TimeZone> zone(TimeZone::createTimeZone(tz));
+ int32_t raw, dst;
+ zone->getOffset(now, false, raw, dst, status);
+ if (U_FAILURE(status)) {
+ errln("TimeZone '%s' getOffset() return error", tz);
+ }
+ assertEquals(u"TimeZone '" + UnicodeString(tz) +
+ u"' getRawOffset() and the raw from getOffset(now, false, raw, dst, status) should not be different but got",
+ zone->getRawOffset(), raw);
+ }
+}
#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/icu4c/source/test/intltest/tztest.h b/icu4c/source/test/intltest/tztest.h
index 8e0a29f..893aad6 100644
--- a/icu4c/source/test/intltest/tztest.h
+++ b/icu4c/source/test/intltest/tztest.h
@@ -103,6 +103,8 @@
void TestGetWindowsID(void);
void TestGetIDForWindowsID(void);
+ void TestCasablancaNameAndOffset22041(void);
+ void TestRawOffsetAndOffsetConsistency22041(void);
static const UDate INTERVAL;
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/timezone/TimeZoneTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/timezone/TimeZoneTest.java
index 48cf764..a69f7ce 100644
--- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/timezone/TimeZoneTest.java
+++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/timezone/TimeZoneTest.java
@@ -2323,6 +2323,36 @@
assertFalse("Compare TimeZoneAdapter with TimeZone", icuChicagoWrapped.equals(icuChicago));
assertTrue("Compare two TimeZoneAdapters", icuChicagoWrapped.equals(icuChicagoWrapped2));
}
+
+ @Test
+ public void TestCasablancaNameAndOffset22041() {
+ String id = "Africa/Casablanca";
+ TimeZone zone = TimeZone.getTimeZone(id);
+ String standardName = zone.getDisplayName(false, TimeZone.LONG, Locale.ENGLISH);
+ String summerName = zone.getDisplayName(true, TimeZone.LONG, Locale.ENGLISH);
+ assertEquals("TimeZone name for Africa/Casablanca should not contain '+02' since it is located in UTC, but got "
+ + standardName, -1, standardName.indexOf("+02"));
+ assertEquals("TimeZone name for Africa/Casablanca should not contain '+02' since it is located in UTC, but got "
+ + summerName, -1, summerName.indexOf("+02"));
+ int[] offsets = new int[2]; // raw = offsets[0], dst = offsets[1]
+ zone.getOffset((new Date()).getTime(), false, offsets);
+ int raw = offsets[0];
+ assertEquals("getRawOffset() and the raw from getOffset(now, false, offset) should not be different but got",
+ zone.getRawOffset(), raw);
+ }
+
+ @Test
+ public void TestRawOffsetAndOffsetConsistency22041() {
+ long now = (new Date()).getTime();
+ int[] offsets = new int[2]; // raw = offsets[0], dst = offsets[1]
+ for (String id : TimeZone.getAvailableIDs()) {
+ TimeZone zone = TimeZone.getTimeZone(id);
+ zone.getOffset((new Date()).getTime(), false, offsets);
+ int raw = offsets[0];
+ assertEquals("getRawOffset() and the raw from getOffset(now, false, offset) should not be different but got",
+ zone.getRawOffset(), raw);
+ }
+ }
}
//eof