From 0b1faa6ffa06ae7bceb17a2d93ee8726eabca4ea Mon Sep 17 00:00:00 2001 From: Yoshito Umaoka Date: Thu, 8 Mar 2012 23:12:02 +0000 Subject: [PATCH] ICU-9162 Implemented getDisplayScript(), provided actual implementation of getVariant() [#9161]. Also improved the implementation of localized name provider to directly access localized data container classes. Added test cases to verify the behavior with locale extension [#9154]. X-SVN-Rev: 31606 --- .../javaspi/util/CurrencyNameProviderICU.java | 15 +- .../javaspi/util/LocaleNameProviderICU.java | 37 +++- .../javaspi/util/TimeZoneNameProviderICU.java | 53 ++--- .../icu/dev/test/localespi/CollatorTest.java | 29 ++- .../test/localespi/DateFormatSymbolsTest.java | 24 ++- .../dev/test/localespi/DateFormatTest.java | 29 ++- .../localespi/DecimalFormatSymbolsTest.java | 27 +++ .../dev/test/localespi/LocaleNameTest.java | 184 ++++++++++++------ .../dev/test/localespi/NumberFormatTest.java | 27 ++- .../ibm/icu/dev/test/localespi/TestUtil.java | 2 +- .../dev/test/localespi/TimeZoneNameTest.java | 60 +++--- 11 files changed, 347 insertions(+), 140 deletions(-) diff --git a/icu4j/main/classes/localespi/src/com/ibm/icu/impl/javaspi/util/CurrencyNameProviderICU.java b/icu4j/main/classes/localespi/src/com/ibm/icu/impl/javaspi/util/CurrencyNameProviderICU.java index 682a3466991..01cf5edaaf9 100644 --- a/icu4j/main/classes/localespi/src/com/ibm/icu/impl/javaspi/util/CurrencyNameProviderICU.java +++ b/icu4j/main/classes/localespi/src/com/ibm/icu/impl/javaspi/util/CurrencyNameProviderICU.java @@ -10,24 +10,25 @@ import java.util.Locale; import java.util.spi.CurrencyNameProvider; import com.ibm.icu.impl.javaspi.ICULocaleServiceProvider; -import com.ibm.icu.util.Currency; +import com.ibm.icu.text.CurrencyDisplayNames; public class CurrencyNameProviderICU extends CurrencyNameProvider { @Override public String getSymbol(String currencyCode, Locale locale) { - Currency cur = Currency.getInstance(currencyCode); - String sym = cur.getSymbol(ICULocaleServiceProvider.toULocaleNoSpecialVariant(locale)); - if (sym.length() == 0 || sym.equals(currencyCode)) { + CurrencyDisplayNames curDispNames = CurrencyDisplayNames.getInstance(ICULocaleServiceProvider.toULocaleNoSpecialVariant(locale)); + String sym = curDispNames.getSymbol(currencyCode); + if (sym == null || sym.equals(currencyCode)) { return null; } return sym; } + //@Override public String getDisplayName(String currencyCode, Locale locale) { - Currency cur = Currency.getInstance(currencyCode); - String name = cur.getDisplayName(locale); - if (name.length() == 0 || name.equals(currencyCode)) { + CurrencyDisplayNames curDispNames = CurrencyDisplayNames.getInstance(ICULocaleServiceProvider.toULocaleNoSpecialVariant(locale)); + String name = curDispNames.getName(currencyCode); + if (name == null || name.equals(currencyCode)) { return null; } return name; diff --git a/icu4j/main/classes/localespi/src/com/ibm/icu/impl/javaspi/util/LocaleNameProviderICU.java b/icu4j/main/classes/localespi/src/com/ibm/icu/impl/javaspi/util/LocaleNameProviderICU.java index 6b86fa0b921..3e2c829306a 100644 --- a/icu4j/main/classes/localespi/src/com/ibm/icu/impl/javaspi/util/LocaleNameProviderICU.java +++ b/icu4j/main/classes/localespi/src/com/ibm/icu/impl/javaspi/util/LocaleNameProviderICU.java @@ -10,15 +10,17 @@ import java.util.Locale; import java.util.spi.LocaleNameProvider; import com.ibm.icu.impl.javaspi.ICULocaleServiceProvider; -import com.ibm.icu.util.ULocale; +import com.ibm.icu.impl.locale.AsciiUtil; +import com.ibm.icu.text.LocaleDisplayNames; public class LocaleNameProviderICU extends LocaleNameProvider { @Override public String getDisplayCountry(String countryCode, Locale locale) { - String id = "und_" + countryCode; - String disp = ULocale.getDisplayCountry(id, ICULocaleServiceProvider.toULocaleNoSpecialVariant(locale)); - if (disp.length() == 0 || disp.equals(countryCode)) { + countryCode = AsciiUtil.toUpperString(countryCode); + String disp = LocaleDisplayNames.getInstance(ICULocaleServiceProvider.toULocaleNoSpecialVariant(locale)) + .regionDisplayName(countryCode); + if (disp == null || disp.length() == 0 || disp.equals(countryCode)) { return null; } return disp; @@ -26,8 +28,21 @@ public class LocaleNameProviderICU extends LocaleNameProvider { @Override public String getDisplayLanguage(String languageCode, Locale locale) { - String disp = ULocale.getDisplayLanguage(languageCode, ICULocaleServiceProvider.toULocaleNoSpecialVariant(locale)); - if (disp.length() == 0 || disp.equals(languageCode)) { + languageCode = AsciiUtil.toLowerString(languageCode); + String disp = LocaleDisplayNames.getInstance(ICULocaleServiceProvider.toULocaleNoSpecialVariant(locale)) + .languageDisplayName(languageCode); + if (disp == null || disp.length() == 0 || disp.equals(languageCode)) { + return null; + } + return disp; + } + + //@Override + public String getDisplayScript(String scriptCode, Locale locale) { + scriptCode = AsciiUtil.toTitleString(scriptCode); + String disp = LocaleDisplayNames.getInstance(ICULocaleServiceProvider.toULocaleNoSpecialVariant(locale)) + .scriptDisplayName(scriptCode); + if (disp == null || disp.length() == 0 || disp.equals(scriptCode)) { return null; } return disp; @@ -35,13 +50,17 @@ public class LocaleNameProviderICU extends LocaleNameProvider { @Override public String getDisplayVariant(String variant, Locale locale) { - // ICU does not support JDK Locale variant names - return null; + variant = AsciiUtil.toUpperString(variant); + String disp = LocaleDisplayNames.getInstance(ICULocaleServiceProvider.toULocaleNoSpecialVariant(locale)) + .variantDisplayName(variant); + if (disp == null || disp.length() == 0 || disp.equals(variant)) { + return null; + } + return disp; } @Override public Locale[] getAvailableLocales() { return ICULocaleServiceProvider.getAvailableLocales(); } - } diff --git a/icu4j/main/classes/localespi/src/com/ibm/icu/impl/javaspi/util/TimeZoneNameProviderICU.java b/icu4j/main/classes/localespi/src/com/ibm/icu/impl/javaspi/util/TimeZoneNameProviderICU.java index 2708e562f7d..9c0d83771ad 100644 --- a/icu4j/main/classes/localespi/src/com/ibm/icu/impl/javaspi/util/TimeZoneNameProviderICU.java +++ b/icu4j/main/classes/localespi/src/com/ibm/icu/impl/javaspi/util/TimeZoneNameProviderICU.java @@ -7,47 +7,36 @@ package com.ibm.icu.impl.javaspi.util; import java.util.Locale; +import java.util.TimeZone; import com.ibm.icu.impl.javaspi.ICULocaleServiceProvider; -import com.ibm.icu.lang.UCharacter; -import com.ibm.icu.util.TimeZone; -import com.ibm.icu.util.ULocale; +import com.ibm.icu.text.TimeZoneNames; +import com.ibm.icu.text.TimeZoneNames.NameType; public class TimeZoneNameProviderICU extends java.util.spi.TimeZoneNameProvider { @Override public String getDisplayName(String ID, boolean daylight, int style, Locale locale) { - TimeZone tz = TimeZone.getFrozenTimeZone(ID); - ULocale actualLocale = ICULocaleServiceProvider.toULocaleNoSpecialVariant(locale); - String disp = tz.getDisplayName(daylight, style, actualLocale); - if (disp.length() == 0) { - return null; - } - // This is ugly hack, but no simple solution to check if - // the localized name was picked up. - int numDigits = 0; - for (int i = 0; i < disp.length(); i++) { - char c = disp.charAt(i); - if (UCharacter.isDigit(c)) { - numDigits++; - } - } - // If there are more than 3 numbers, this code assume GMT format was used. - if (numDigits >= 3) { - return null; - } - - if (daylight) { - // ICU uses standard name for daylight name when the zone does not use - // daylight saving time. - - // This is yet another ugly hack to support the JDK's behavior - String stdDisp = tz.getDisplayName(false, style, actualLocale); - if (disp.equals(stdDisp)) { - return null; + String dispName = null; + boolean[] isSystemID = new boolean[1]; + String canonicalID = com.ibm.icu.util.TimeZone.getCanonicalID(ID, isSystemID); + if (isSystemID[0]) { + long date = System.currentTimeMillis(); + TimeZoneNames tznames = TimeZoneNames.getInstance(ICULocaleServiceProvider.toULocaleNoSpecialVariant(locale)); + switch (style) { + case TimeZone.LONG: + dispName = daylight ? + tznames.getDisplayName(canonicalID, NameType.LONG_DAYLIGHT, date) : + tznames.getDisplayName(canonicalID, NameType.LONG_STANDARD, date); + break; + case TimeZone.SHORT: + dispName = daylight ? + tznames.getDisplayName(canonicalID, NameType.SHORT_DAYLIGHT, date) : + tznames.getDisplayName(canonicalID, NameType.SHORT_STANDARD, date); + break; } } - return disp; + return dispName; } @Override diff --git a/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/CollatorTest.java b/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/CollatorTest.java index 9ef945771e0..9b4677801b3 100644 --- a/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/CollatorTest.java +++ b/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/CollatorTest.java @@ -1,6 +1,6 @@ /* ******************************************************************************* - * Copyright (C) 2008, International Business Machines Corporation and * + * Copyright (C) 2008-2012, International Business Machines Corporation and * * others. All Rights Reserved. * ******************************************************************************* */ @@ -11,6 +11,8 @@ import java.text.Collator; import java.util.Locale; import com.ibm.icu.dev.test.TestFmwk; +import com.ibm.icu.impl.jdkadapter.CollatorICU; +import com.ibm.icu.util.ULocale; public class CollatorTest extends TestFmwk { public static void main(String[] args) throws Exception { @@ -129,4 +131,29 @@ public class CollatorTest extends TestFmwk { } } } + + public void TestCollationKeyword() { + // ICU provider variant is appended + ULocale uloc0 = new ULocale("de_DE_" + TestUtil.ICU_VARIANT + "@collation=phonebook"); + Locale loc = uloc0.toLocale(); + // On Java 7+, locale extension is preserved + ULocale uloc = ULocale.forLocale(loc); + String nsType = uloc.getKeywordValue("collation"); + if (nsType == null) { + // Java 6 - skip this test + return; + } + + Collator jdkColl = Collator.getInstance(loc); + boolean isPhonebook = false; + if (jdkColl instanceof CollatorICU) { + ULocale ulocJdkColl = ((CollatorICU)jdkColl).unwrap().getLocale(ULocale.VALID_LOCALE); + if (ulocJdkColl.getKeywordValue("collation").equals("phonebook")) { + isPhonebook = true; + } + } + if (!isPhonebook) { + errln("FAIL: The collation type is not phonebook"); + } + } } diff --git a/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/DateFormatSymbolsTest.java b/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/DateFormatSymbolsTest.java index d9357ddbfdb..770430e2a95 100644 --- a/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/DateFormatSymbolsTest.java +++ b/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/DateFormatSymbolsTest.java @@ -1,6 +1,6 @@ /* ******************************************************************************* - * Copyright (C) 2008, International Business Machines Corporation and * + * Copyright (C) 2008-2012, International Business Machines Corporation and * * others. All Rights Reserved. * ******************************************************************************* */ @@ -10,6 +10,7 @@ import java.text.DateFormatSymbols; import java.util.Locale; import com.ibm.icu.dev.test.TestFmwk; +import com.ibm.icu.util.ULocale; public class DateFormatSymbolsTest extends TestFmwk { public static void main(String[] args) throws Exception { @@ -180,4 +181,25 @@ public class DateFormatSymbolsTest extends TestFmwk { } } } + + public void TestCalendarKeyword() { + // ICU provider variant is appended + ULocale uloc0 = new ULocale("en_US_" + TestUtil.ICU_VARIANT + "@calendar=japanese"); + Locale loc = uloc0.toLocale(); + // On Java 7+, locale extension is preserved + ULocale uloc = ULocale.forLocale(loc); + String calType = uloc.getKeywordValue("calendar"); + if (calType == null) { + // Java 6 - skip this test + return; + } + + DateFormatSymbols jdkDfs = DateFormatSymbols.getInstance(loc); + com.ibm.icu.text.DateFormatSymbols icuDfs = com.ibm.icu.text.DateFormatSymbols.getInstance(uloc); + + // Check the length of era, so we can check if Japanese calendar is picked up + if (jdkDfs.getEras().length != icuDfs.getEras().length) { + errln("FAIL: Calendar keyword was ignored"); + } + } } diff --git a/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/DateFormatTest.java b/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/DateFormatTest.java index 8bef67fd4ab..8f2c0b672aa 100644 --- a/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/DateFormatTest.java +++ b/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/DateFormatTest.java @@ -1,6 +1,6 @@ /* ******************************************************************************* - * Copyright (C) 2008, International Business Machines Corporation and * + * Copyright (C) 2008-2012, International Business Machines Corporation and * * others. All Rights Reserved. * ******************************************************************************* */ @@ -8,10 +8,13 @@ package com.ibm.icu.dev.test.localespi; import java.text.DateFormat; import java.text.ParseException; +import java.util.Calendar; import java.util.Date; import java.util.Locale; import com.ibm.icu.dev.test.TestFmwk; +import com.ibm.icu.impl.jdkadapter.CalendarICU; +import com.ibm.icu.util.ULocale; public class DateFormatTest extends TestFmwk { @@ -193,4 +196,28 @@ public class DateFormatTest extends TestFmwk { errln("FAIL: ICU DateFormat returned a result different from JDK for th_TH_TH"); } } + + public void TestCalendarKeyword() { + // ICU provider variant is appended + ULocale uloc0 = new ULocale("en_US_" + TestUtil.ICU_VARIANT + "@calendar=buddhist"); + Locale loc = uloc0.toLocale(); + // On Java 7+, locale extension is preserved + ULocale uloc = ULocale.forLocale(loc); + String calType = uloc.getKeywordValue("calendar"); + if (calType == null) { + // Java 6 - skip this test + return; + } + + DateFormat jdkDfmt = DateFormat.getDateInstance(DateFormat.FULL, loc); + Calendar cal = jdkDfmt.getCalendar(); + boolean isBuddhist = false; + if (cal instanceof CalendarICU) { + com.ibm.icu.util.Calendar icuCal = ((CalendarICU)cal).unwrap(); + isBuddhist = icuCal.getType().equals("buddhist"); + } + if (!isBuddhist) { + errln("FAIL: Calendar types is not Buddhist"); + } + } } diff --git a/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/DecimalFormatSymbolsTest.java b/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/DecimalFormatSymbolsTest.java index fb7a09c5693..5b83442b96d 100644 --- a/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/DecimalFormatSymbolsTest.java +++ b/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/DecimalFormatSymbolsTest.java @@ -11,6 +11,7 @@ import java.util.Currency; import java.util.Locale; import com.ibm.icu.dev.test.TestFmwk; +import com.ibm.icu.util.ULocale; public class DecimalFormatSymbolsTest extends TestFmwk { public static void main(String[] args) throws Exception { @@ -156,4 +157,30 @@ public class DecimalFormatSymbolsTest extends TestFmwk { checkEquivalence(decfs.getPerMill(), decfsEnUS.getPerMill(), loc, "getPerMill"); checkEquivalence(decfs.getZeroDigit(), decfsEnUS.getZeroDigit(), loc, "getZeroDigit"); } + + public void TestKeywords() { + // ICU provider variant is appended + ULocale uloc0 = new ULocale("en_US_" + TestUtil.ICU_VARIANT + "@numbers=Arab;currency=EUR"); + Locale loc = uloc0.toLocale(); + // On Java 7+, locale extension is preserved + ULocale uloc = ULocale.forLocale(loc); + String nsType = uloc.getKeywordValue("numbers"); + if (nsType == null) { + // Java 6 - skip this test + return; + } + + DecimalFormatSymbols jdkDecfs = DecimalFormatSymbols.getInstance(loc); + com.ibm.icu.text.DecimalFormatSymbols icuDecfs = com.ibm.icu.text.DecimalFormatSymbols.getInstance(uloc); + // Check digit 0 + if (jdkDecfs.getDigit() != icuDecfs.getDigit()) { + errln("FAIL: Different decimal digit - via JDK: " + jdkDecfs.getDigit() + ", with ICU: " + icuDecfs.getDigit()); + } + + String jdkCurrencyCode = jdkDecfs.getCurrency().getCurrencyCode(); + String icuCurrencyCode = icuDecfs.getCurrency().getCurrencyCode(); + if (!jdkCurrencyCode.equals(icuCurrencyCode)) { + errln("FAIL: Different currency code - via JDK: " + jdkCurrencyCode + ", with ICU: " + icuCurrencyCode); + } + } } diff --git a/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/LocaleNameTest.java b/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/LocaleNameTest.java index 750670f2f55..0b79f3ecbcd 100644 --- a/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/LocaleNameTest.java +++ b/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/LocaleNameTest.java @@ -6,7 +6,10 @@ */ package com.ibm.icu.dev.test.localespi; +import java.lang.reflect.Method; +import java.util.HashSet; import java.util.Locale; +import java.util.Set; import com.ibm.icu.dev.test.TestFmwk; import com.ibm.icu.util.ULocale; @@ -16,6 +19,18 @@ public class LocaleNameTest extends TestFmwk { new LocaleNameTest().run(args); } + private static final Method GETDISPLAYSCRIPT_METHOD; + + static { + Method mGetDisplayScript = null; + try { + mGetDisplayScript = Locale.class.getMethod("getDisplayScript", new Class[] {Locale.class}); + } catch (Exception e) { + // fall through + } + GETDISPLAYSCRIPT_METHOD = mGetDisplayScript; + } + public void TestLanguageNames() { Locale[] locales = Locale.getAvailableLocales(); StringBuffer icuid = new StringBuffer(); @@ -76,6 +91,67 @@ public class LocaleNameTest extends TestFmwk { } } + public void TestScriptNames() { + if (GETDISPLAYSCRIPT_METHOD == null) { + logln("INFO: Locale#getDisplayScript(Locale) is not available."); + return; + } + + Locale[] locales = Locale.getAvailableLocales(); + for (Locale inLocale : locales) { + if (TestUtil.isProblematicIBMLocale(inLocale)) { + logln("Skipped " + inLocale); + continue; + } + + ULocale inULocale = ULocale.forLocale(inLocale); + Locale inLocaleICU = TestUtil.toICUExtendedLocale(inLocale); + for (ULocale forULocale : ULocale.getAvailableLocales()) { + if (forULocale.getScript().length() == 0) { + continue; + } + Locale forLocale = forULocale.toLocale(); + String icuname = forULocale.getDisplayScript(inULocale); + if (icuname.equals(forULocale.getScript()) || icuname.length() == 0) { + continue; + } + + String name = null; + try { + name = (String)GETDISPLAYSCRIPT_METHOD.invoke(forLocale, new Object[] {inLocale}); + } catch (Exception e) { + errln("FAIL: JDK Locale#getDisplayScript(\"" + inLocale + "\") throws exception: " + e.getMessage()); + continue; + } + + if (TestUtil.isICUExtendedLocale(inLocale)) { + // The name should be taken from ICU + if (!name.equals(icuname)) { + errln("FAIL: Script name by ICU is " + icuname + ", but got " + name + + " for locale " + forLocale + " in locale " + inLocale); + } + } else { + // The name might be taken from JDK + if (!name.equals(icuname)) { + logln("INFO: Script name by JDK is " + name + ", but " + icuname + + " in ICU, for locale " + forLocale + " in locale " + inLocale); + } + // Try explicit ICU locale (xx_yy_ICU) + try { + name = (String)GETDISPLAYSCRIPT_METHOD.invoke(forLocale, new Object[] {inLocaleICU}); + } catch (Exception e) { + errln("FAIL: JDK Locale#getDisplayScript(\"" + inLocaleICU + "\") throws exception: " + e.getMessage()); + continue; + } + if (!name.equals(icuname)) { + errln("FAIL: Script name by ICU is " + icuname + ", but got " + name + + " for locale " + forLocale + " in locale " + inLocaleICU); + } + } + } + } + } + public void TestCountryNames() { Locale[] locales = Locale.getAvailableLocales(); for (Locale inLocale : locales) { @@ -121,29 +197,22 @@ public class LocaleNameTest extends TestFmwk { } } - public void TestVariantNames() { - // [Note] - // This test passed OK without any error for several reasons. - // When I changed ICU provider's special variant from "ICU" to - // "ICU4J" (#9155), this test started failing. The primary - // reason was mis-use of ULocale.getDisplayVariant(String, ULocale) - // in the test code below. The first argument should be complete - // locale ID, not variant only string. However, fixing this won't - // resolve the issue because of another ICU bug (multiple variant subtag - // issue #9160). - // - // Actually, we do not have LocaleNameProvider#getDisplayVariant - // implementation (#9161). The current implementation always returns - // null. So, the test case below happened to work, but it did not - // check anything meaningful. For now, the test case is disabled. - // We'll revisit this test case when #9160 and #9161 are resolved. - // 2012-03-01 yoshito - logln("ICU does not support LocaleNameProvider#getDisplayVariant"); - if (true) return; + Set locales = new HashSet(); + for (Locale l : Locale.getAvailableLocales()) { + locales.add(l); + } + // Add some locales with variant + final Locale[] additionalLocales = { + new Locale("fr", "FR", "1694acad"), + new Locale("de", "DE", "1901"), + new Locale("en", "US", "boont"), + new Locale("el", "GR", "monoton"), + }; + for (Locale l : additionalLocales) { + locales.add(l); + } - Locale[] locales = Locale.getAvailableLocales(); - StringBuffer icuid = new StringBuffer(); for (Locale inLocale : locales) { if (TestUtil.isProblematicIBMLocale(inLocale)) { logln("Skipped " + inLocale); @@ -153,48 +222,47 @@ public class LocaleNameTest extends TestFmwk { ULocale inULocale = ULocale.forLocale(inLocale); Locale inLocaleICU = TestUtil.toICUExtendedLocale(inLocale); for (Locale forLocale : locales) { - if (forLocale.getVariant().length() == 0) { - continue; - } - icuid.setLength(0); - icuid.append(forLocale.getLanguage()); - String country = forLocale.getCountry(); - String variant = forLocale.getVariant(); - if (country.length() != 0) { - icuid.append("_"); - icuid.append(country); - } - if (variant.length() != 0) { - if (country.length() == 0) { - icuid.append("_"); - } - icuid.append("_"); - icuid.append(variant); - } - ULocale forULocale = new ULocale(icuid.toString()); -// String icuname = ULocale.getDisplayVariant(forULocale.getVariant(), inULocale); - String icuname = forULocale.getDisplayVariant(inULocale); - if (icuname.equals(forULocale.getVariant()) || icuname.length() == 0) { + String locVar = forLocale.getVariant(); + if (locVar.length() == 0) { continue; } + // Note: JDK resolves a display name for each variant subtag + String[] locVarSubtags = locVar.split("_"); - String name = forLocale.getDisplayVariant(inLocale); - if (TestUtil.isICUExtendedLocale(inLocale)) { - // The name should be taken from ICU - if (!name.equals(icuname)) { - errln("FAIL: Variant name by ICU is " + icuname + ", but got " + name - + " for locale " + forLocale + " in locale " + inLocale); + for (String locSingleVar : locVarSubtags) { + if (locSingleVar.equals(TestUtil.ICU_VARIANT)) { + continue; } - } else { - if (!name.equals(icuname)) { - logln("INFO: Variant name by JDK is " + name + ", but " + icuname + - " in ICU, for locale " + forLocale + " in locale " + inLocale); + Locale forLocaleSingleVar = new Locale(forLocale.getLanguage(), forLocale.getCountry(), locSingleVar); + ULocale forULocaleSingleVar = new ULocale("und_ZZ_" + locSingleVar); + String icuname = forULocaleSingleVar.getDisplayVariant(inULocale); + if (icuname.equals(locSingleVar) || icuname.length() == 0) { + continue; } - // Try explicit ICU locale (xx_yy_ICU) - name = forLocale.getDisplayVariant(inLocaleICU); - if (!name.equals(icuname)) { - errln("FAIL: Variant name by ICU is " + icuname + ", but got " + name - + " for locale " + forLocale + " in locale " + inLocaleICU); + + String name = forLocaleSingleVar.getDisplayVariant(inLocale); + if (name.equalsIgnoreCase(locSingleVar)) { + // ICU does not have any localized display name. + // Note: ICU turns variant to upper case string, while Java does not. + continue; + } + if (TestUtil.isICUExtendedLocale(inLocale)) { + // The name should be taken from ICU + if (!name.equals(icuname)) { + errln("FAIL: Variant name by ICU is " + icuname + ", but got " + name + + " for locale " + forLocaleSingleVar + " in locale " + inLocale); + } + } else { + if (!name.equals(icuname)) { + logln("INFO: Variant name by JDK is " + name + ", but " + icuname + + " in ICU, for locale " + forLocaleSingleVar + " in locale " + inLocale); + } + // Try explicit ICU locale (xx_yy_ICU) + name = forLocaleSingleVar.getDisplayVariant(inLocaleICU); + if (!name.equals(icuname)) { + errln("FAIL: Variant name by ICU is " + icuname + ", but got " + name + + " for locale " + forLocaleSingleVar + " in locale " + inLocaleICU); + } } } } diff --git a/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/NumberFormatTest.java b/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/NumberFormatTest.java index b8811824e46..4ae63877a2a 100644 --- a/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/NumberFormatTest.java +++ b/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/NumberFormatTest.java @@ -1,6 +1,6 @@ /* ******************************************************************************* - * Copyright (C) 2008, International Business Machines Corporation and * + * Copyright (C) 2008-2012, International Business Machines Corporation and * * others. All Rights Reserved. * ******************************************************************************* */ @@ -13,6 +13,7 @@ import java.text.ParseException; import java.util.Locale; import com.ibm.icu.dev.test.TestFmwk; +import com.ibm.icu.util.ULocale; public class NumberFormatTest extends TestFmwk { public static void main(String[] args) throws Exception { @@ -288,4 +289,28 @@ public class NumberFormatTest extends TestFmwk { } } } + + public void TestKeywords() { + // ICU provider variant is appended + ULocale uloc0 = new ULocale("en_US_" + TestUtil.ICU_VARIANT + "@numbers=Arab;currency=EUR"); + Locale loc = uloc0.toLocale(); + // On Java 7+, locale extension is preserved + ULocale uloc = ULocale.forLocale(loc); + String nsType = uloc.getKeywordValue("numbers"); + if (nsType == null) { + // Java 6 - skip this test + return; + } + + NumberFormat jdkNfmt = NumberFormat.getCurrencyInstance(loc); + com.ibm.icu.text.NumberFormat icuNfmt = com.ibm.icu.text.NumberFormat.getCurrencyInstance(uloc); + + final double num = 12345.67d; + String jdkOut = jdkNfmt.format(num); + String icuOut = icuNfmt.format(num); + + if (!jdkOut.equals(icuOut)) { + errln("FAIL: JDK number format with Locale " + loc + " is " + jdkOut + ", expected: " + icuOut); + } + } } diff --git a/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/TestUtil.java b/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/TestUtil.java index ddfebb49fe7..f182d911488 100644 --- a/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/TestUtil.java +++ b/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/TestUtil.java @@ -13,7 +13,7 @@ import com.ibm.icu.util.ULocale.Builder; public class TestUtil { - private static final String ICU_VARIANT = "ICU4J"; + static final String ICU_VARIANT = "ICU4J"; private static final String ICU_VARIANT_SUFFIX = "_ICU4J"; public static Locale toICUExtendedLocale(Locale locale) { diff --git a/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/TimeZoneNameTest.java b/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/TimeZoneNameTest.java index 5052a4477aa..42ee22c7301 100644 --- a/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/TimeZoneNameTest.java +++ b/icu4j/main/tests/localespi/src/com/ibm/icu/dev/test/localespi/TimeZoneNameTest.java @@ -10,7 +10,8 @@ import java.util.Locale; import java.util.TimeZone; import com.ibm.icu.dev.test.TestFmwk; -import com.ibm.icu.lang.UCharacter; +import com.ibm.icu.text.TimeZoneNames; +import com.ibm.icu.text.TimeZoneNames.NameType; import com.ibm.icu.util.ULocale; public class TimeZoneNameTest extends TestFmwk { @@ -29,16 +30,13 @@ public class TimeZoneNameTest extends TestFmwk { } for (String tzid : tzids) { - com.ibm.icu.util.TimeZone tzIcu = com.ibm.icu.util.TimeZone.getTimeZone(tzid); - // Java does not pick up time zone names for ID/Locale from an SPI // when long standard display name is not available. - String icuStdLong = getIcuDisplayName(tzIcu, false, TimeZone.LONG, loc); + String icuStdLong = getIcuDisplayName(tzid, false, TimeZone.LONG, loc); if (icuStdLong != null) { - TimeZone tz = TimeZone.getTimeZone(tzid); - checkDisplayNamePair(TimeZone.SHORT, tz, tzIcu, loc, warningOnly); - checkDisplayNamePair(TimeZone.LONG, tz, tzIcu, loc, warningOnly); + checkDisplayNamePair(TimeZone.SHORT, tzid, loc, warningOnly); + checkDisplayNamePair(TimeZone.LONG, tzid, loc, warningOnly); } else { logln("Localized long standard name is not available for " + tzid + " in locale " + loc + " in ICU"); @@ -47,7 +45,7 @@ public class TimeZoneNameTest extends TestFmwk { } } - private void checkDisplayNamePair(int style, TimeZone tz, com.ibm.icu.util.TimeZone icuTz, Locale loc, boolean warnOnly) { + private void checkDisplayNamePair(int style, String tzid, Locale loc, boolean warnOnly) { /* Note: There are two problems here. * * It looks Java 6 requires a TimeZoneNameProvider to return both standard name and daylight name @@ -60,36 +58,40 @@ public class TimeZoneNameTest extends TestFmwk { * saving time even daylight name is requested. */ - String icuStdName = getIcuDisplayName(icuTz, false, style, loc); - String icuDstName = getIcuDisplayName(icuTz, true, style, loc); + String icuStdName = getIcuDisplayName(tzid, false, style, loc); + String icuDstName = getIcuDisplayName(tzid, true, style, loc); if (icuStdName != null && icuDstName != null && !icuStdName.equals(icuDstName)) { - checkDisplayName(false, style, tz, loc, icuStdName, warnOnly); - checkDisplayName(true, style, tz, loc, icuDstName, warnOnly); + checkDisplayName(false, style, tzid, loc, icuStdName, warnOnly); + checkDisplayName(true, style, tzid, loc, icuDstName, warnOnly); } } - private String getIcuDisplayName(com.ibm.icu.util.TimeZone icuTz, boolean daylight, int style, Locale loc) { - ULocale uloc = ULocale.forLocale(loc); - boolean shortStyle = (style == TimeZone.SHORT); - String icuname = icuTz.getDisplayName(daylight, - (shortStyle ? com.ibm.icu.util.TimeZone.SHORT : com.ibm.icu.util.TimeZone.LONG), - uloc); - int numDigits = 0; - for (int i = 0; i < icuname.length(); i++) { - if (UCharacter.isDigit(icuname.charAt(i))) { - numDigits++; + private String getIcuDisplayName(String tzid, boolean daylight, int style, Locale loc) { + String icuName = null; + boolean[] isSystemID = new boolean[1]; + String canonicalID = com.ibm.icu.util.TimeZone.getCanonicalID(tzid, isSystemID); + if (isSystemID[0]) { + long date = System.currentTimeMillis(); + TimeZoneNames tznames = TimeZoneNames.getInstance(ULocale.forLocale(loc)); + switch (style) { + case TimeZone.LONG: + icuName = daylight ? + tznames.getDisplayName(canonicalID, NameType.LONG_DAYLIGHT, date) : + tznames.getDisplayName(canonicalID, NameType.LONG_STANDARD, date); + break; + case TimeZone.SHORT: + icuName = daylight ? + tznames.getDisplayName(canonicalID, NameType.SHORT_DAYLIGHT, date) : + tznames.getDisplayName(canonicalID, NameType.SHORT_STANDARD, date); + break; } } - if (numDigits >= 3) { - // ICU does not have the localized name - return null; - } - return icuname; + return icuName; } - private void checkDisplayName(boolean daylight, int style, TimeZone tz, Locale loc, String icuname, boolean warnOnly) { + private void checkDisplayName(boolean daylight, int style, String tzid, Locale loc, String icuname, boolean warnOnly) { String styleStr = (style == TimeZone.SHORT) ? "SHORT" : "LONG"; - + TimeZone tz = TimeZone.getTimeZone(tzid); String name = tz.getDisplayName(daylight, style, loc); if (TestUtil.isICUExtendedLocale(loc)) { -- 2.40.0