diff --git a/icu4j/src/com/ibm/icu/dev/test/format/TimeZoneFormatTest.java b/icu4j/src/com/ibm/icu/dev/test/format/TimeZoneFormatTest.java index c630a4fbe7..2214ad5c64 100644 --- a/icu4j/src/com/ibm/icu/dev/test/format/TimeZoneFormatTest.java +++ b/icu4j/src/com/ibm/icu/dev/test/format/TimeZoneFormatTest.java @@ -109,15 +109,24 @@ public class TimeZoneFormatTest extends com.ibm.icu.dev.test.TestFmwk { outtz.getOffset(DATES[datidx].getTime(), false, outOffsets); if (PATTERNS[patidx].equals("VVVV")) { - // Location: time zone rule must be preserved. + // Location: time zone rule must be preserved except + // zones not actually associated with a specific location. + // Time zones in this category do not have "/" in its ID. String canonicalID = TimeZone.getCanonicalID(tzids[tzidx]); if (canonicalID != null && !outtz.getID().equals(canonicalID)) { // Canonical ID did not match - check the rules if (!((BasicTimeZone)outtz).hasEquivalentTransitions(tz, low, high)) { - errln("Canonical round trip failed; tz=" + tzids[tzidx] - + ", locale=" + LOCALES[locidx] + ", pattern=" + PATTERNS[patidx] - + ", time=" + DATES[datidx].getTime() + ", str=" + tzstr - + ", outtz=" + outtz.getID()); + if (canonicalID.indexOf('/') == -1) { + logln("Canonical round trip failed (as expected); tz=" + tzids[tzidx] + + ", locale=" + LOCALES[locidx] + ", pattern=" + PATTERNS[patidx] + + ", time=" + DATES[datidx].getTime() + ", str=" + tzstr + + ", outtz=" + outtz.getID()); + } else { + errln("Canonical round trip failed; tz=" + tzids[tzidx] + + ", locale=" + LOCALES[locidx] + ", pattern=" + PATTERNS[patidx] + + ", time=" + DATES[datidx].getTime() + ", str=" + tzstr + + ", outtz=" + outtz.getID()); + } } } } else { diff --git a/icu4j/src/com/ibm/icu/impl/ZoneStringFormat.java b/icu4j/src/com/ibm/icu/impl/ZoneStringFormat.java index b57343855f..55f5a24859 100644 --- a/icu4j/src/com/ibm/icu/impl/ZoneStringFormat.java +++ b/icu4j/src/com/ibm/icu/impl/ZoneStringFormat.java @@ -269,21 +269,26 @@ public class ZoneStringFormat { } } else { if (tzid.startsWith("Etc/")) { - // "Etc/xxx" is not associated with a location, so localized GMT format - // is always used as generic location format. + // "Etc/xxx" is not associated with a specific location, so localized + // GMT format is always used as generic location format. zstrarray[ZSIDX_LOCATION] = null; } else { - // When a new time zone ID, which is actually associated with a region, - // is added in tzdata, but the current CLDR data does not have the - // information yet, ICU creates a generic location string based on + // When a new time zone ID, which is actually associated with a specific + // location, is added in tzdata, but the current CLDR data does not have + // the information yet, ICU creates a generic location string based on // the ID. This implementation supports canonical time zone round trip // with format pattern "VVVV". See #6602 for the details. String location = tzid; int slashIdx = location.lastIndexOf('/'); - if (slashIdx != -1) { + if (slashIdx == -1) { + // A time zone ID without slash in the tz database is not + // associated with a specific location. For instances, + // MET, CET, EET and WET fall into this catetory. + zstrarray[ZSIDX_LOCATION] = null; + } else { location = tzid.substring(slashIdx + 1); + zstrarray[ZSIDX_LOCATION] = regionFmt.format(new Object[] {location}); } - zstrarray[ZSIDX_LOCATION] = regionFmt.format(new Object[] {location}); } }