From: Shane Carr Date: Sat, 30 Sep 2017 00:58:52 +0000 (+0000) Subject: ICU-11666 Integrating narrow currency symbol in ICU4J; follow-up to r40519. X-Git-Tag: release-60-rc~79 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7df399c9645743ec64ae115f04a02fecfcd2aa2a;p=icu ICU-11666 Integrating narrow currency symbol in ICU4J; follow-up to r40519. X-SVN-Rev: 40520 --- diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/MutablePatternModifier.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/MutablePatternModifier.java index ad61dd01965..df1fa909930 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/MutablePatternModifier.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/MutablePatternModifier.java @@ -320,11 +320,13 @@ public class MutablePatternModifier implements Modifier, SymbolProvider, CharSeq case AffixUtils.TYPE_PERMILLE: return symbols.getPerMillString(); case AffixUtils.TYPE_CURRENCY_SINGLE: - // UnitWidth ISO or HIDDEN overrides the singular currency symbol. + // UnitWidth ISO, HIDDEN, or NARROW overrides the singular currency symbol. if (unitWidth == UnitWidth.ISO_CODE) { return currency.getCurrencyCode(); } else if (unitWidth == UnitWidth.HIDDEN) { return ""; + } else if (unitWidth == UnitWidth.NARROW) { + return currency.getName(symbols.getULocale(), Currency.NARROW_SYMBOL_NAME, null); } else { return currency.getName(symbols.getULocale(), Currency.SYMBOL_NAME, null); } @@ -339,7 +341,7 @@ public class MutablePatternModifier implements Modifier, SymbolProvider, CharSeq case AffixUtils.TYPE_CURRENCY_QUAD: return "\uFFFD"; case AffixUtils.TYPE_CURRENCY_QUINT: - return "\uFFFD"; + return currency.getName(symbols.getULocale(), Currency.NARROW_SYMBOL_NAME, null); default: throw new AssertionError(); } diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/Parse.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/Parse.java index 4835b674845..79bc9e03874 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/Parse.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/Parse.java @@ -1920,6 +1920,9 @@ public class Parse { case AffixUtils.TYPE_CURRENCY_SINGLE: case AffixUtils.TYPE_CURRENCY_DOUBLE: case AffixUtils.TYPE_CURRENCY_TRIPLE: + case AffixUtils.TYPE_CURRENCY_QUAD: + case AffixUtils.TYPE_CURRENCY_QUINT: + case AffixUtils.TYPE_CURRENCY_OVERFLOW: resolvedCurrency = true; break; default: diff --git a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberFormatter.java b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberFormatter.java index 0530acac21b..8021ca22f58 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberFormatter.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberFormatter.java @@ -68,7 +68,7 @@ public final class NumberFormatter { * meters in en-CA: * * * *

- * * The narrow format for currencies is not currently supported; this is a known issue that will be fixed in a - * future version. See #11666 for more information. - * - *

* This enum is similar to {@link com.ibm.icu.text.MeasureFormat.FormatWidth}. * * @draft ICU 60 diff --git a/icu4j/main/classes/core/src/com/ibm/icu/util/Currency.java b/icu4j/main/classes/core/src/com/ibm/icu/util/Currency.java index 8b99564781a..ef3d5be7bac 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/util/Currency.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/util/Currency.java @@ -24,6 +24,7 @@ import java.util.MissingResourceException; import java.util.Set; import com.ibm.icu.impl.CacheBase; +import com.ibm.icu.impl.CurrencyData.CurrencyDisplayInfo; import com.ibm.icu.impl.ICUCache; import com.ibm.icu.impl.ICUData; import com.ibm.icu.impl.ICUDebug; @@ -87,6 +88,21 @@ public class Currency extends MeasureUnit { */ public static final int PLURAL_LONG_NAME = 2; + /** + * Selector for getName() indicating the narrow currency symbol. + * The narrow currency symbol is similar to the regular currency + * symbol, but it always takes the shortest form: for example, + * "$" instead of "US$". + * + * This method assumes that the currency data provider is the ICU4J + * built-in data provider. If it is not, an exception is thrown. + * + * @internal + * @deprecated ICU 60: This API is ICU internal only. + */ + @Deprecated + public static final int NARROW_SYMBOL_NAME = 3; + private static final EquivalenceRelation EQUIVALENT_CURRENCY_SYMBOLS = new EquivalenceRelation() .add("\u00a5", "\uffe5") @@ -570,10 +586,6 @@ public class Currency extends MeasureUnit { * @stable ICU 3.2 */ public String getName(ULocale locale, int nameStyle, boolean[] isChoiceFormat) { - if (!(nameStyle == SYMBOL_NAME || nameStyle == LONG_NAME)) { - throw new IllegalArgumentException("bad name style: " + nameStyle); - } - // We no longer support choice format data in names. Data should not contain // choice patterns. if (isChoiceFormat != null) { @@ -581,7 +593,22 @@ public class Currency extends MeasureUnit { } CurrencyDisplayNames names = CurrencyDisplayNames.getInstance(locale); - return nameStyle == SYMBOL_NAME ? names.getSymbol(subType) : names.getName(subType); + switch (nameStyle) { + case SYMBOL_NAME: + return names.getSymbol(subType); + case NARROW_SYMBOL_NAME: + // CurrencyDisplayNames is the public interface. + // CurrencyDisplayInfo is ICU's standard implementation. + if (!(names instanceof CurrencyDisplayInfo)) { + throw new UnsupportedOperationException( + "Cannot get narrow symbol from custom currency display name provider"); + } + return ((CurrencyDisplayInfo) names).getNarrowSymbol(subType); + case LONG_NAME: + return names.getName(subType); + default: + throw new IllegalArgumentException("bad name style: " + nameStyle); + } } /** diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java index 3696bd43678..3354f9b7760 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java @@ -5827,4 +5827,17 @@ public class NumberFormatTest extends TestFmwk { assertEquals("Plural few", "3.00 dvorak", df.format(3)); assertEquals("Plural other", "5.80 US dollars", df.format(5.8)); } + + @Test + public void TestNarrowCurrencySymbols() { + DecimalFormat df = (DecimalFormat) NumberFormat.getCurrencyInstance(ULocale.CANADA); + df.setCurrency(Currency.getInstance("USD")); + expect2(df, 123.45, "US$123.45"); + String pattern = df.toPattern(); + pattern = pattern.replace("¤", "¤¤¤¤¤"); + df.applyPattern(pattern); + // Note: Narrow currency is not parseable because of ambiguity. + assertEquals("Narrow currency symbol for USD in en_CA is $", + "$123.45", df.format(123.45)); + } } diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/AffixUtilsTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/AffixUtilsTest.java index 0af776c2205..d796d7e1329 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/AffixUtilsTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/AffixUtilsTest.java @@ -41,8 +41,7 @@ public class AffixUtilsTest { case AffixUtils.TYPE_CURRENCY_QUAD: return "\uFFFD"; case AffixUtils.TYPE_CURRENCY_QUINT: - // TODO: Add support for narrow currency symbols here. - return "\uFFFD"; + return "@"; case AffixUtils.TYPE_CURRENCY_OVERFLOW: return "\uFFFD"; default: @@ -99,10 +98,10 @@ public class AffixUtilsTest { {"¤¤", true, 2, "XXX"}, {"¤¤¤", true, 3, "long name"}, {"¤¤¤¤", true, 4, "\uFFFD"}, - {"¤¤¤¤¤", true, 5, "\uFFFD"}, + {"¤¤¤¤¤", true, 5, "@"}, {"¤¤¤¤¤¤", true, 6, "\uFFFD"}, {"¤¤¤a¤¤¤¤", true, 8, "long namea\uFFFD"}, - {"a¤¤¤¤b¤¤¤¤¤c", true, 12, "a\uFFFDb\uFFFDc"}, + {"a¤¤¤¤b¤¤¤¤¤c", true, 12, "a\uFFFDb@c"}, {"¤!", true, 2, "$!"}, {"¤¤!", true, 3, "XXX!"}, {"¤¤¤!", true, 4, "long name!"}, diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java index 2de062f1735..cb843a80aac 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java @@ -557,14 +557,13 @@ public class NumberFormatterApiTest { // The full currency symbol is not shown in NARROW format. // NOTE: This example is in the documentation. - // FIXME: Narrow Currency does not currently work; see #11666 assertFormatSingle( "Currency Difference between Narrow and Short (Narrow Version)", "", NumberFormatter.with().unit(USD).unitWidth(UnitWidth.NARROW), ULocale.forLanguageTag("en-CA"), 5.43, - "US$5.43"); + "$5.43"); assertFormatSingle( "Currency Difference between Narrow and Short (Short Version)",