From bc5b7e5c35dbe951194c5547b53d5be1ca21b85e Mon Sep 17 00:00:00 2001 From: Yoshito Umaoka Date: Fri, 4 Jan 2013 23:31:17 +0000 Subject: [PATCH] ICU-9733 Use primary zone data (formerly singleCoutries) for generic location names in ICU4C. Synchronized metaZones.res including primaryZones data with ICU4C trunk. X-SVN-Rev: 33013 --- .../ibm/icu/impl/TimeZoneGenericNames.java | 10 +-- .../core/src/com/ibm/icu/impl/ZoneMeta.java | 62 ++++++++++++++----- icu4j/main/shared/data/icutzdata.jar | 4 +- .../icu/dev/test/format/DateFormatTest.java | 12 +++- 4 files changed, 63 insertions(+), 25 deletions(-) diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/TimeZoneGenericNames.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/TimeZoneGenericNames.java index ddd0945baee..ffcaf78cf22 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/TimeZoneGenericNames.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/TimeZoneGenericNames.java @@ -1,6 +1,6 @@ /* ******************************************************************************* - * Copyright (C) 2011-2012, International Business Machines Corporation and * + * Copyright (C) 2011-2013, International Business Machines Corporation and * * others. All Rights Reserved. * ******************************************************************************* */ @@ -27,6 +27,7 @@ import com.ibm.icu.text.TimeZoneNames.MatchInfo; import com.ibm.icu.text.TimeZoneNames.NameType; import com.ibm.icu.util.BasicTimeZone; import com.ibm.icu.util.Freezable; +import com.ibm.icu.util.Output; import com.ibm.icu.util.TimeZone; import com.ibm.icu.util.TimeZone.SystemTimeZoneType; import com.ibm.icu.util.TimeZoneTransition; @@ -232,11 +233,12 @@ public class TimeZoneGenericNames implements Serializable, Freezable isPrimary = new Output(); + String countryCode = ZoneMeta.getCanonicalCountry(canonicalTzID, isPrimary); if (countryCode != null) { - String country = getLocaleDisplayNames().regionDisplayName(countryCode); - if (ZoneMeta.getSingleCountry(canonicalTzID) != null) { + if (isPrimary.value) { // If this is only the single zone in the country, use the country name + String country = getLocaleDisplayNames().regionDisplayName(countryCode); name = formatPattern(Pattern.REGION_FORMAT, country); } else { // If there are multiple zones including this in the country, diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/ZoneMeta.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/ZoneMeta.java index 48dbad65a12..f0cc3c5f2de 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/ZoneMeta.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/ZoneMeta.java @@ -1,6 +1,6 @@ /* ********************************************************************** -* Copyright (c) 2003-2011 International Business Machines +* Copyright (c) 2003-2013 International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * Author: Alan Liu @@ -19,6 +19,7 @@ import java.util.Set; import java.util.TreeSet; import com.ibm.icu.text.NumberFormat; +import com.ibm.icu.util.Output; import com.ibm.icu.util.SimpleTimeZone; import com.ibm.icu.util.TimeZone; import com.ibm.icu.util.TimeZone.SystemTimeZoneType; @@ -457,25 +458,52 @@ public final class ZoneMeta { } /** - * Return the country code if this is a 'single' time zone that can fallback to just - * the country, otherwise return null. (Note, one must also check the locale data - * to see that there is a localization for the country in order to implement - * tr#35 appendix J step 5.) + * Return the canonical country code for this tzid. If we have none, or if the time zone + * is not associated with a country or unknown, return null. When the given zone is the + * primary zone of the country, true is set to isPrimary. */ - public static String getSingleCountry(String tzid) { - String country = getCanonicalCountry(tzid); - if (country != null) { - Boolean isSingle = SINGLE_COUNTRY_CACHE.get(tzid); - if (isSingle == null) { - Set ids = TimeZone.getAvailableIDs(SystemTimeZoneType.CANONICAL_LOCATION, country, null); - assert(ids.size() >= 1); - isSingle = Boolean.valueOf(ids.size() <= 1); - SINGLE_COUNTRY_CACHE.put(tzid, isSingle); - } - if (!isSingle) { - country = null; + public static String getCanonicalCountry(String tzid, Output isPrimary) { + isPrimary.value = Boolean.FALSE; + + String country = getRegion(tzid); + if (country != null && country.equals(kWorld)) { + return null; + } + + // Check the cache + Boolean singleZone = SINGLE_COUNTRY_CACHE.get(tzid); + if (singleZone == null) { + Set ids = TimeZone.getAvailableIDs(SystemTimeZoneType.CANONICAL_LOCATION, country, null); + assert(ids.size() >= 1); + singleZone = Boolean.valueOf(ids.size() <= 1); + SINGLE_COUNTRY_CACHE.put(tzid, singleZone); + } + + if (singleZone) { + isPrimary.value = Boolean.TRUE; + } else { + // Note: We may cache the primary zone map in future. + + // Even a country has multiple zones, one of them might be + // dominant and treated as a primary zone. + try { + UResourceBundle bundle = UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, "metaZones"); + UResourceBundle primaryZones = bundle.get("primaryZones"); + String primaryZone = primaryZones.getString(country); + if (tzid.equals(primaryZone)) { + isPrimary.value = Boolean.TRUE; + } else { + // The given ID might not be a canonical ID + String canonicalID = getCanonicalCLDRID(tzid); + if (canonicalID != null && canonicalID.equals(primaryZone)) { + isPrimary.value = Boolean.TRUE; + } + } + } catch (MissingResourceException e) { + // ignore } } + return country; } diff --git a/icu4j/main/shared/data/icutzdata.jar b/icu4j/main/shared/data/icutzdata.jar index a1ce9dd074d..fe00a73c861 100755 --- a/icu4j/main/shared/data/icutzdata.jar +++ b/icu4j/main/shared/data/icutzdata.jar @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a7875b8b6a12647a40923f9034a042f64e644e2139f0974df972e496f68fad31 -size 97787 +oid sha256:04f78ad2df4e4be5a6b1e70786e495ec9e759c9dad26e482c2a06eb842c2a90c +size 97803 diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatTest.java index cbc863fa33b..b4e3ced00f3 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatTest.java @@ -1,6 +1,6 @@ /* ******************************************************************************* - * Copyright (C) 2001-2012, International Business Machines Corporation and * + * Copyright (C) 2001-2013, International Business Machines Corporation and * * others. All Rights Reserved. * ******************************************************************************* */ @@ -857,7 +857,11 @@ public class DateFormatTest extends com.ibm.icu.dev.test.TestFmwk { { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "India Standard Time", "+5:30" }, { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "India Time", "Asia/Calcutta" }, { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "India Standard Time", "Asia/Calcutta" }, - + + // Proper CLDR primary zone support #9733 + { "en", "Asia/Shanghai", "2013-01-01T00:00:00Z", "VVVV", "China Time", "Asia/Shanghai" }, + { "en", "Asia/Harbin", "2013-01-01T00:00:00Z", "VVVV", "Harbin Time", "Asia/Harbin" }, + // ========== { "de", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" }, @@ -1070,6 +1074,10 @@ public class DateFormatTest extends com.ibm.icu.dev.test.TestFmwk { { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "\u5370\u5ea6\u65f6\u95f4", "Asia/Calcutta" }, { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\u5370\u5EA6\u65f6\u95f4", "Asia/Calcutta" }, + // Proper CLDR primary zone support #9733 + { "zh", "Asia/Shanghai", "2013-01-01T00:00:00Z", "VVVV", "\u4e2d\u56fd\u65f6\u95f4", "Asia/Shanghai" }, + { "zh", "Asia/Harbin", "2013-01-01T00:00:00Z", "VVVV", "\u54c8\u5c14\u6ee8\u65f6\u95f4", "Asia/Harbin" }, + // ========== { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" }, -- 2.40.0