diff --git a/icu4c/source/i18n/timezone.cpp b/icu4c/source/i18n/timezone.cpp index 23b29f051fd..1b078a51506 100644 --- a/icu4c/source/i18n/timezone.cpp +++ b/icu4c/source/i18n/timezone.cpp @@ -994,22 +994,41 @@ TimeZone::createTimeZoneIDEnumeration( return TZEnumeration::create(zoneType, region, rawOffset, ec); } +StringEnumeration* U_EXPORT2 +TimeZone::createEnumeration(UErrorCode& status) { + return TZEnumeration::create(UCAL_ZONE_TYPE_ANY, NULL, NULL, status); +} + +StringEnumeration* U_EXPORT2 +TimeZone::createEnumerationForRawOffset(int32_t rawOffset, UErrorCode& status) { + return TZEnumeration::create(UCAL_ZONE_TYPE_ANY, NULL, &rawOffset, status); +} + +StringEnumeration* U_EXPORT2 +TimeZone::createEnumerationForRegion(const char* region, UErrorCode& status) { + return TZEnumeration::create(UCAL_ZONE_TYPE_ANY, region, NULL, status); +} + +// +// Next 3 methods are equivalent to above, but ignores UErrorCode. +// These methods were deprecated in ICU 70. + StringEnumeration* U_EXPORT2 TimeZone::createEnumeration() { UErrorCode ec = U_ZERO_ERROR; - return TZEnumeration::create(UCAL_ZONE_TYPE_ANY, NULL, NULL, ec); + return createEnumeration(ec); } StringEnumeration* U_EXPORT2 TimeZone::createEnumeration(int32_t rawOffset) { UErrorCode ec = U_ZERO_ERROR; - return TZEnumeration::create(UCAL_ZONE_TYPE_ANY, NULL, &rawOffset, ec); + return createEnumerationForRawOffset(rawOffset, ec); } StringEnumeration* U_EXPORT2 -TimeZone::createEnumeration(const char* country) { +TimeZone::createEnumeration(const char* region) { UErrorCode ec = U_ZERO_ERROR; - return TZEnumeration::create(UCAL_ZONE_TYPE_ANY, country, NULL, ec); + return createEnumerationForRegion(region, ec); } // --------------------------------------- diff --git a/icu4c/source/i18n/tzfmt.cpp b/icu4c/source/i18n/tzfmt.cpp index 302ad8e4aa6..c16d4131682 100644 --- a/icu4c/source/i18n/tzfmt.cpp +++ b/icu4c/source/i18n/tzfmt.cpp @@ -2780,15 +2780,17 @@ static void U_CALLCONV initZoneIdTrie(UErrorCode &status) { status = U_MEMORY_ALLOCATION_ERROR; return; } - StringEnumeration *tzenum = TimeZone::createEnumeration(); - const UnicodeString *id; - while ((id = tzenum->snext(status)) != NULL) { - const UChar* uid = ZoneMeta::findTimeZoneID(*id); - if (uid) { - gZoneIdTrie->put(uid, const_cast(uid), status); + StringEnumeration *tzenum = TimeZone::createEnumeration(status); + if (U_SUCCESS(status)) { + const UnicodeString *id; + while ((id = tzenum->snext(status)) != NULL) { + const UChar* uid = ZoneMeta::findTimeZoneID(*id); + if (uid) { + gZoneIdTrie->put(uid, const_cast(uid), status); + } } + delete tzenum; } - delete tzenum; } diff --git a/icu4c/source/i18n/unicode/gregocal.h b/icu4c/source/i18n/unicode/gregocal.h index df037c65040..4c79944a6ff 100644 --- a/icu4c/source/i18n/unicode/gregocal.h +++ b/icu4c/source/i18n/unicode/gregocal.h @@ -78,9 +78,9 @@ U_NAMESPACE_BEGIN * \code * // get the supported ids for GMT-08:00 (Pacific Standard Time) * UErrorCode success = U_ZERO_ERROR; - * const StringEnumeration *ids = TimeZone::createEnumeration(-8 * 60 * 60 * 1000); + * const StringEnumeration *ids = TimeZone::createEnumeration(-8 * 60 * 60 * 1000, success); * // if no ids were returned, something is wrong. get out. - * if (ids == 0 || ids->count(success) == 0) { + * if (U_FAILURE(success)) { * return; * } * diff --git a/icu4c/source/i18n/unicode/timezone.h b/icu4c/source/i18n/unicode/timezone.h index 571d7e077d1..762caac94c7 100644 --- a/icu4c/source/i18n/unicode/timezone.h +++ b/icu4c/source/i18n/unicode/timezone.h @@ -199,15 +199,28 @@ public: const int32_t* rawOffset, UErrorCode& ec); +#ifndef U_HIDE_DEPRECATED_API /** * Returns an enumeration over all recognized time zone IDs. (i.e., * all strings that createTimeZone() accepts) * * @return an enumeration object, owned by the caller. - * @stable ICU 2.4 + * @deprecated ICU 70 Use createEnumeration(UErrorCode&) instead. */ static StringEnumeration* U_EXPORT2 createEnumeration(); +#endif // U_HIDE_DEPRECATED_API + /** + * Returns an enumeration over all recognized time zone IDs. (i.e., + * all strings that createTimeZone() accepts) + * + * @param status Receives the status. + * @return an enumeration object, owned by the caller. + * @stable ICU 70 + */ + static StringEnumeration* U_EXPORT2 createEnumeration(UErrorCode& status); + +#ifndef U_HIDE_DEPRECATED_API /** * Returns an enumeration over time zone IDs with a given raw * offset from GMT. There may be several times zones with the @@ -223,21 +236,57 @@ public: * @param rawOffset an offset from GMT in milliseconds, ignoring * the effect of daylight savings time, if any * @return an enumeration object, owned by the caller - * @stable ICU 2.4 + * @deprecated ICU 70 Use createEnumerationForRawOffset(int32_t,UErrorCode&) instead. */ static StringEnumeration* U_EXPORT2 createEnumeration(int32_t rawOffset); +#endif // U_HIDE_DEPRECATED_API + + /** + * Returns an enumeration over time zone IDs with a given raw + * offset from GMT. There may be several times zones with the + * same GMT offset that differ in the way they handle daylight + * savings time. For example, the state of Arizona doesn't + * observe daylight savings time. If you ask for the time zone + * IDs corresponding to GMT-7:00, you'll get back an enumeration + * over two time zone IDs: "America/Denver," which corresponds to + * Mountain Standard Time in the winter and Mountain Daylight Time + * in the summer, and "America/Phoenix", which corresponds to + * Mountain Standard Time year-round, even in the summer. + * + * @param rawOffset an offset from GMT in milliseconds, ignoring + * the effect of daylight savings time, if any + * @param status Receives the status. + * @return an enumeration object, owned by the caller + * @stable ICU 70 + */ + static StringEnumeration* U_EXPORT2 createEnumerationForRawOffset(int32_t rawOffset, UErrorCode& status); + +#ifndef U_HIDE_DEPRECATED_API + /** + * Returns an enumeration over time zone IDs associated with the + * given region. Some zones are affiliated with no region + * (e.g., "UTC"); these may also be retrieved, as a group. + * + * @param region The ISO 3166 two-letter country code, or NULL to + * retrieve zones not affiliated with any region. + * @return an enumeration object, owned by the caller + * @deprecated ICU 70 Use createEnumerationForRegion(const char*,UErrorCode&) instead. + */ + static StringEnumeration* U_EXPORT2 createEnumeration(const char* region); +#endif // U_HIDE_DEPRECATED_API /** * Returns an enumeration over time zone IDs associated with the - * given country. Some zones are affiliated with no country + * given region. Some zones are affiliated with no region * (e.g., "UTC"); these may also be retrieved, as a group. * - * @param country The ISO 3166 two-letter country code, or NULL to - * retrieve zones not affiliated with any country. + * @param region The ISO 3166 two-letter country code, or NULL to + * retrieve zones not affiliated with any region. + * @param status Receives the status. * @return an enumeration object, owned by the caller - * @stable ICU 2.4 + * @stable ICU 70 */ - static StringEnumeration* U_EXPORT2 createEnumeration(const char* country); + static StringEnumeration* U_EXPORT2 createEnumerationForRegion(const char* region, UErrorCode& status); /** * Returns the number of IDs in the equivalency group that diff --git a/icu4c/source/test/intltest/calregts.cpp b/icu4c/source/test/intltest/calregts.cpp index 459623be6ac..1a5a972810c 100644 --- a/icu4c/source/test/intltest/calregts.cpp +++ b/icu4c/source/test/intltest/calregts.cpp @@ -260,8 +260,8 @@ CalendarRegressionTest::test4031502() // This bug actually occurs on Windows NT as well, and doesn't // require the host zone to be set; it can be set in Java. UErrorCode status = U_ZERO_ERROR; - StringEnumeration* ids = TimeZone::createEnumeration(); - if (ids == NULL) { + StringEnumeration* ids = TimeZone::createEnumeration(status); + if (U_FAILURE(status)) { dataerrln("Unable to create TimeZone Enumeration."); return; } @@ -328,12 +328,12 @@ void CalendarRegressionTest::test4035301() void CalendarRegressionTest::test4040996() { int32_t count = 0; - StringEnumeration* ids = TimeZone::createEnumeration(-8 * 60 * 60 * 1000); - if (ids == NULL) { + UErrorCode status = U_ZERO_ERROR; + StringEnumeration* ids = TimeZone::createEnumerationForRawOffset(-8 * 60 * 60 * 1000, status); + if (U_FAILURE(status)) { dataerrln("Unable to create TimeZone enumeration."); return; } - UErrorCode status = U_ZERO_ERROR; count = ids->count(status); (void)count; // Suppress set but not used warning. SimpleTimeZone *pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, *ids->snext(status)); @@ -2682,9 +2682,13 @@ void CalendarRegressionTest::TestTimeZoneTransitionAdd() { UErrorCode ec = U_ZERO_ERROR; Locale locale(Locale::getUS()); // could also be CHINA SimpleDateFormat dateFormat("MM/dd/yyyy HH:mm z", locale, ec); + if (U_FAILURE(ec)) { + dataerrln("FAIL: Constructing SimpleDateFormat"); + return; + } - StringEnumeration *tz = TimeZone::createEnumeration(); - if (tz == NULL) { + StringEnumeration *tz = TimeZone::createEnumeration(ec); + if (U_FAILURE(ec)) { dataerrln("FAIL: TimeZone::createEnumeration"); return; } diff --git a/icu4c/source/test/intltest/dtfmttst.cpp b/icu4c/source/test/intltest/dtfmttst.cpp index 18a19a4980f..18dc02af3c4 100644 --- a/icu4c/source/test/intltest/dtfmttst.cpp +++ b/icu4c/source/test/intltest/dtfmttst.cpp @@ -264,8 +264,8 @@ void DateFormatTest::TestWallyWedel() * A String array for the time zone ids. */ int32_t ids_length; - StringEnumeration* ids = TimeZone::createEnumeration(); - if (ids == NULL) { + StringEnumeration* ids = TimeZone::createEnumeration(status); + if (U_FAILURE(status)) { dataerrln("Unable to create TimeZone enumeration."); if (sdf != NULL) { delete sdf; diff --git a/icu4c/source/test/intltest/tzfmttst.cpp b/icu4c/source/test/intltest/tzfmttst.cpp index 0daa45c5a4d..9808de04cda 100644 --- a/icu4c/source/test/intltest/tzfmttst.cpp +++ b/icu4c/source/test/intltest/tzfmttst.cpp @@ -158,7 +158,11 @@ TimeZoneFormatTest::TestTimeZoneRoundTrip(void) { LOCALES = Locale::getAvailableLocales(nLocales); } - StringEnumeration *tzids = TimeZone::createEnumeration(); + StringEnumeration *tzids = TimeZone::createEnumeration(status); + if (U_FAILURE(status)) { + dataerrln("Unable to create TimeZone enumeration"); + return; + } int32_t inRaw, inDst; int32_t outRaw, outDst; @@ -729,9 +733,12 @@ void TimeZoneFormatTest::RunAdoptDefaultThreadSafeTests(int32_t threadNumber) { if (threadNumber % 2 == 0) { for (int32_t i = 0; i < kAdoptDefaultIteration; i++) { std::unique_ptr timezones( - icu::TimeZone::createEnumeration()); + icu::TimeZone::createEnumeration(status)); // Fails with missing data. - if (!assertTrue(WHERE, (bool)timezones, false, true)) {return;} + if (U_FAILURE(status)) { + dataerrln("Unable to create TimeZone enumeration"); + return; + } while (const icu::UnicodeString* timezone = timezones->snext(status)) { status = U_ZERO_ERROR; icu::TimeZone::adoptDefault(icu::TimeZone::createTimeZone(*timezone)); @@ -1301,9 +1308,9 @@ TimeZoneFormatTest::TestFormatCustomZone(void) { void TimeZoneFormatTest::TestFormatTZDBNamesAllZoneCoverage(void) { UErrorCode status = U_ZERO_ERROR; - LocalPointer tzids(TimeZone::createEnumeration()); - if (tzids.getAlias() == nullptr) { - dataerrln("%s %d tzids is null", __FILE__, __LINE__); + LocalPointer tzids(TimeZone::createEnumeration(status)); + if (U_FAILURE(status)) { + dataerrln("Unable to create TimeZone enumeration", __FILE__, __LINE__); return; } const UnicodeString *tzid; diff --git a/icu4c/source/test/intltest/tzregts.cpp b/icu4c/source/test/intltest/tzregts.cpp index 1a38b830f7e..bc8a0029765 100644 --- a/icu4c/source/test/intltest/tzregts.cpp +++ b/icu4c/source/test/intltest/tzregts.cpp @@ -517,8 +517,8 @@ void TimeZoneRegressionTest:: Test4151406() { //try { UErrorCode ec = U_ZERO_ERROR; int32_t count; - StringEnumeration* ids = TimeZone::createEnumeration(rawoffset); - if (ids == NULL) { + StringEnumeration* ids = TimeZone::createEnumerationForRawOffset(rawoffset, ec); + if (U_FAILURE(ec)) { dataerrln("Fail: TimeZone::createEnumeration(rawoffset)"); continue; } diff --git a/icu4c/source/test/intltest/tzrulets.cpp b/icu4c/source/test/intltest/tzrulets.cpp index f683d8ee1b2..fbbceb4c3e9 100644 --- a/icu4c/source/test/intltest/tzrulets.cpp +++ b/icu4c/source/test/intltest/tzrulets.cpp @@ -83,7 +83,7 @@ TestZIDEnumeration::TestZIDEnumeration(UBool all) : idx(0) { UErrorCode status = U_ZERO_ERROR; if (all) { - tzenum = TimeZone::createEnumeration(); + tzenum = TimeZone::createEnumeration(status); len = tzenum->count(status); } else { tzenum = NULL; diff --git a/icu4c/source/test/intltest/tztest.cpp b/icu4c/source/test/intltest/tztest.cpp index 4b1b34820af..89b6f54fe86 100644 --- a/icu4c/source/test/intltest/tztest.cpp +++ b/icu4c/source/test/intltest/tztest.cpp @@ -14,6 +14,7 @@ #include "unicode/simpletz.h" #include "unicode/calendar.h" #include "unicode/gregocal.h" +#include "unicode/localpointer.h" #include "unicode/resbund.h" #include "unicode/strenum.h" #include "unicode/uversion.h" @@ -425,12 +426,16 @@ TimeZoneTest::TestGetAvailableIDs913() UnicodeString str; UnicodeString buf(u"TimeZone::createEnumeration() = { "); int32_t s_length; - StringEnumeration* s = TimeZone::createEnumeration(); - if (s == NULL) { + StringEnumeration* s = TimeZone::createEnumeration(ec); + LocalPointer tmp1(TimeZone::createEnumeration(), ec); + if (U_FAILURE(ec) || s == NULL) { dataerrln("Unable to create TimeZone enumeration"); return; } s_length = s->count(ec); + if (s_length != tmp1->count(ec)) { + errln("TimeZone::createEnumeration() with no status args returns a different count."); + } for (i = 0; i < s_length;++i) { if (i > 0) buf += ", "; if ((i & 1) == 0) { @@ -481,8 +486,16 @@ TimeZoneTest::TestGetAvailableIDs913() buf.truncate(0); buf += "TimeZone::createEnumeration(GMT+01:00) = { "; - s = TimeZone::createEnumeration(1 * U_MILLIS_PER_HOUR); + s = TimeZone::createEnumerationForRawOffset(1 * U_MILLIS_PER_HOUR, ec); + LocalPointer tmp2(TimeZone::createEnumeration(1 * U_MILLIS_PER_HOUR), ec); + if (U_FAILURE(ec)) { + dataerrln("Unable to create TimeZone enumeration for GMT+1"); + return; + } s_length = s->count(ec); + if (s_length != tmp2->count(ec)) { + errln("TimeZone::createEnumeration(GMT+01:00) with no status args returns a different count."); + } for (i = 0; i < s_length;++i) { if (i > 0) buf += ", "; buf += *s->snext(ec); @@ -495,9 +508,17 @@ TimeZoneTest::TestGetAvailableIDs913() buf.truncate(0); buf += "TimeZone::createEnumeration(US) = { "; - s = TimeZone::createEnumeration("US"); + s = TimeZone::createEnumerationForRegion("US", ec); + LocalPointer tmp3(TimeZone::createEnumeration("US"), ec); + if (U_FAILURE(ec)) { + dataerrln("Unable to create TimeZone enumeration for US"); + return; + } s_length = s->count(ec); - for (i = 0; i < s_length;++i) { + if (s_length != tmp3->count(ec)) { + errln("TimeZone::createEnumeration(\"US\") with no status args returns a different count."); + } + for (i = 0; i < s_length; ++i) { if (i > 0) buf += ", "; buf += *s->snext(ec); } @@ -1720,8 +1741,8 @@ void TimeZoneTest::TestCountries() { // Asia/Tokyo isn't. Vice versa for the "JP" group. UErrorCode ec = U_ZERO_ERROR; int32_t n; - StringEnumeration* s = TimeZone::createEnumeration("US"); - if (s == NULL) { + StringEnumeration* s = TimeZone::createEnumerationForRegion("US", ec); + if (U_FAILURE(ec)) { dataerrln("Unable to create TimeZone enumeration for US"); return; } @@ -1731,7 +1752,7 @@ void TimeZoneTest::TestCountries() { UnicodeString tokyoZone("Asia/Tokyo", ""); int32_t i; - if (s == NULL || n <= 0) { + if (n <= 0) { dataerrln("FAIL: TimeZone::createEnumeration() returned nothing"); return; } @@ -1750,7 +1771,11 @@ void TimeZoneTest::TestCountries() { } delete s; - s = TimeZone::createEnumeration("JP"); + s = TimeZone::createEnumerationForRegion("JP", ec); + if (U_FAILURE(ec)) { + dataerrln("Unable to create TimeZone enumeration for JP"); + return; + } n = s->count(ec); la = FALSE; tokyo = FALSE; @@ -1767,8 +1792,12 @@ void TimeZoneTest::TestCountries() { errln("FAIL: " + laZone + " in JP = " + la); errln("FAIL: " + tokyoZone + " in JP = " + tokyo); } - StringEnumeration* s1 = TimeZone::createEnumeration("US"); - StringEnumeration* s2 = TimeZone::createEnumeration("US"); + StringEnumeration* s1 = TimeZone::createEnumerationForRegion("US", ec); + StringEnumeration* s2 = TimeZone::createEnumerationForRegion("US", ec); + if (U_FAILURE(ec)) { + dataerrln("Unable to create TimeZone enumeration for US"); + return; + } for(i=0;isnext(ec); if(id1==NULL || U_FAILURE(ec)){ @@ -2118,8 +2147,8 @@ void TimeZoneTest::TestCanonicalID() { // Walk through equivalency groups UErrorCode ec = U_ZERO_ERROR; int32_t s_length, i, j, k; - StringEnumeration* s = TimeZone::createEnumeration(); - if (s == NULL) { + StringEnumeration* s = TimeZone::createEnumeration(ec); + if (U_FAILURE(ec)) { dataerrln("Unable to create TimeZone enumeration"); return; } diff --git a/icu4c/source/test/perf/normperf/dtfmtrtperf.h b/icu4c/source/test/perf/normperf/dtfmtrtperf.h index 76a2293c340..22dab949838 100644 --- a/icu4c/source/test/perf/normperf/dtfmtrtperf.h +++ b/icu4c/source/test/perf/normperf/dtfmtrtperf.h @@ -143,7 +143,7 @@ public: const Locale *LOCALES; LOCALES = testLocales; - StringEnumeration *tzids = TimeZone::createEnumeration(); + StringEnumeration *tzids = TimeZone::createEnumeration(*status); if (U_FAILURE(*status)) { //errln("tzids->count failed"); return; diff --git a/icu4c/source/tools/tzcode/icuzdump.cpp b/icu4c/source/tools/tzcode/icuzdump.cpp index 783f63d22b3..78d84ff445a 100644 --- a/icu4c/source/tools/tzcode/icuzdump.cpp +++ b/icu4c/source/tools/tzcode/icuzdump.cpp @@ -213,7 +213,9 @@ class ZoneIterator { public: ZoneIterator(UBool bAll = false) { if (bAll) { - zenum = TimeZone::createEnumeration(); + UErrorCode status = U_ZERO_ERROR; + zenum = TimeZone::createEnumeration(status); + // TODO: Add error case handling later. } else { zenum = NULL;