From 434a94ec4d57847f35aa7617dbe4c6d7e6312406 Mon Sep 17 00:00:00 2001 From: Yoshito Umaoka Date: Wed, 12 Jun 2013 20:56:06 +0000 Subject: [PATCH] ICU-10209 Fixed odd TimeType problem with ZONE_ID, ZONE_ID_SHORT and EXEMPLAR_LOCATION in TimeZoneFormat#format. Also added generic TimeZoneFormat test cases. X-SVN-Rev: 33819 --- icu4c/source/i18n/tzfmt.cpp | 45 +++++----- icu4c/source/test/intltest/tzfmttst.cpp | 109 ++++++++++++++++++++++++ icu4c/source/test/intltest/tzfmttst.h | 1 + 3 files changed, 136 insertions(+), 19 deletions(-) diff --git a/icu4c/source/i18n/tzfmt.cpp b/icu4c/source/i18n/tzfmt.cpp index ab5b451d359..d4ac316481a 100644 --- a/icu4c/source/i18n/tzfmt.cpp +++ b/icu4c/source/i18n/tzfmt.cpp @@ -639,6 +639,9 @@ TimeZoneFormat::format(UTimeZoneFormatStyle style, const TimeZone& tz, UDate dat if (timeType) { *timeType = UTZFMT_TIME_TYPE_UNKNOWN; } + + UBool noOffsetFormatFallback = FALSE; + switch (style) { case UTZFMT_STYLE_GENERIC_LOCATION: formatGeneric(tz, UTZGNM_LOCATION, date, name); @@ -655,12 +658,33 @@ TimeZoneFormat::format(UTimeZoneFormatStyle style, const TimeZone& tz, UDate dat case UTZFMT_STYLE_SPECIFIC_SHORT: formatSpecific(tz, UTZNM_SHORT_STANDARD, UTZNM_SHORT_DAYLIGHT, date, name, timeType); break; + + case UTZFMT_STYLE_ZONE_ID: + tz.getID(name); + noOffsetFormatFallback = TRUE; + break; + case UTZFMT_STYLE_ZONE_ID_SHORT: + { + const UChar* shortID = ZoneMeta::getShortID(tz); + if (shortID == NULL) { + shortID = UNKNOWN_SHORT_ZONE_ID; + } + name.setTo(shortID, -1); + } + noOffsetFormatFallback = TRUE; + break; + + case UTZFMT_STYLE_EXEMPLAR_LOCATION: + formatExemplarLocation(tz, name); + noOffsetFormatFallback = TRUE; + break; + default: // will be handled below break; } - if (name.isEmpty()) { + if (name.isEmpty() && !noOffsetFormatFallback) { UErrorCode status = U_ZERO_ERROR; int32_t rawOffset, dstOffset; tz.getOffset(date, FALSE, rawOffset, dstOffset, status); @@ -719,25 +743,8 @@ TimeZoneFormat::format(UTimeZoneFormatStyle style, const TimeZone& tz, UDate dat case UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FULL: formatOffsetISO8601Extended(offset, FALSE, FALSE, FALSE, name, status); break; - - case UTZFMT_STYLE_ZONE_ID: - tz.getID(name); - break; - - case UTZFMT_STYLE_ZONE_ID_SHORT: - { - const UChar* shortID = ZoneMeta::getShortID(tz); - if (shortID == NULL) { - shortID = UNKNOWN_SHORT_ZONE_ID; - } - name.setTo(shortID, -1); - } - break; - - case UTZFMT_STYLE_EXEMPLAR_LOCATION: - formatExemplarLocation(tz, name); - break; } + if (timeType) { *timeType = (dstOffset != 0) ? UTZFMT_TIME_TYPE_DAYLIGHT : UTZFMT_TIME_TYPE_STANDARD; } diff --git a/icu4c/source/test/intltest/tzfmttst.cpp b/icu4c/source/test/intltest/tzfmttst.cpp index 2662d962848..ffdaeae279c 100644 --- a/icu4c/source/test/intltest/tzfmttst.cpp +++ b/icu4c/source/test/intltest/tzfmttst.cpp @@ -75,6 +75,7 @@ TimeZoneFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name TESTCASE(1, TestTimeRoundTrip); TESTCASE(2, TestParse); TESTCASE(3, TestISOFormat); + TESTCASE(4, TestFormat); default: name = ""; break; } } @@ -916,4 +917,112 @@ TimeZoneFormatTest::TestISOFormat(void) { } +typedef struct { + const char* locale; + const char* tzid; + UDate date; + UTimeZoneFormatStyle style; + const char* expected; + UTimeZoneFormatTimeType timeType; +} FormatTestData; + +void +TimeZoneFormatTest::TestFormat(void) { + UDate dateJan = 1358208000000.0; // 2013-01-15T00:00:00Z + UDate dateJul = 1373846400000.0; // 2013-07-15T00:00:00Z + + const FormatTestData DATA[] = { + { + "en", + "America/Los_Angeles", + dateJan, + UTZFMT_STYLE_GENERIC_LOCATION, + "Los Angeles Time", + UTZFMT_TIME_TYPE_UNKNOWN + }, + { + "en", + "America/Los_Angeles", + dateJan, + UTZFMT_STYLE_GENERIC_LONG, + "Pacific Time", + UTZFMT_TIME_TYPE_UNKNOWN + }, + { + "en", + "America/Los_Angeles", + dateJan, + UTZFMT_STYLE_SPECIFIC_LONG, + "Pacific Standard Time", + UTZFMT_TIME_TYPE_STANDARD + }, + { + "en", + "America/Los_Angeles", + dateJul, + UTZFMT_STYLE_SPECIFIC_LONG, + "Pacific Daylight Time", + UTZFMT_TIME_TYPE_DAYLIGHT + }, + { + "ja", + "America/Los_Angeles", + dateJan, + UTZFMT_STYLE_ZONE_ID, + "America/Los_Angeles", + UTZFMT_TIME_TYPE_UNKNOWN + }, + { + "fr", + "America/Los_Angeles", + dateJul, + UTZFMT_STYLE_ZONE_ID_SHORT, + "uslax", + UTZFMT_TIME_TYPE_UNKNOWN + }, + { + "en", + "America/Los_Angeles", + dateJan, + UTZFMT_STYLE_EXEMPLAR_LOCATION, + "Los Angeles", + UTZFMT_TIME_TYPE_UNKNOWN + }, + + { + "ja", + "Asia/Tokyo", + dateJan, + UTZFMT_STYLE_GENERIC_LONG, + "\\u65E5\\u672C\\u6A19\\u6E96\\u6642", + UTZFMT_TIME_TYPE_UNKNOWN + }, + + {0, 0, 0.0, UTZFMT_STYLE_GENERIC_LOCATION, 0, UTZFMT_TIME_TYPE_UNKNOWN} + }; + + for (int32_t i = 0; DATA[i].locale; i++) { + UErrorCode status = U_ZERO_ERROR; + LocalPointer tzfmt(TimeZoneFormat::createInstance(Locale(DATA[i].locale), status)); + if (U_FAILURE(status)) { + dataerrln("Fail TimeZoneFormat::createInstance: %s", u_errorName(status)); + continue; + } + + LocalPointer tz(TimeZone::createTimeZone(DATA[i].tzid)); + UnicodeString out; + UTimeZoneFormatTimeType timeType; + + tzfmt->format(DATA[i].style, *(tz.getAlias()), DATA[i].date, out, &timeType); + UnicodeString expected(DATA[i].expected, -1, US_INV); + expected = expected.unescape(); + + assertEquals(UnicodeString("Format result for ") + DATA[i].tzid + " (Test Case " + i + ")", expected, out); + if (DATA[i].timeType != timeType) { + dataerrln(UnicodeString("Formatted time zone type (Test Case ") + i + "), returned=" + + timeType + ", expected=" + DATA[i].timeType); + } + } +} + #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/icu4c/source/test/intltest/tzfmttst.h b/icu4c/source/test/intltest/tzfmttst.h index 4635711f555..3d81a82b6dd 100644 --- a/icu4c/source/test/intltest/tzfmttst.h +++ b/icu4c/source/test/intltest/tzfmttst.h @@ -22,6 +22,7 @@ class TimeZoneFormatTest : public IntlTest { void TestTimeRoundTrip(void); void TestParse(void); void TestISOFormat(void); + void TestFormat(void); }; #endif /* #if !UCONFIG_NO_FORMATTING */ -- 2.40.0