ICU-11666 Integrating narrow currency symbol in ICU4J; follow-up to r40519.

X-SVN-Rev: 40520
This commit is contained in:
Shane Carr 2017-09-30 00:58:52 +00:00
parent 9c8165a44d
commit 7df399c964
7 changed files with 57 additions and 18 deletions

View file

@ -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();
}

View file

@ -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:

View file

@ -68,7 +68,7 @@ public final class NumberFormatter {
* meters in <em>en-CA</em>:
*
* <ul>
* <li>NARROW*: "$123.00" and "123 m"
* <li>NARROW: "$123.00" and "123 m"
* <li>SHORT: "US$ 123.00" and "123 m"
* <li>FULL_NAME: "123.00 US dollars" and "123 meters"
* <li>ISO_CODE: "USD 123.00" and undefined behavior
@ -76,10 +76,6 @@ public final class NumberFormatter {
* </ul>
*
* <p>
* * 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.
*
* <p>
* This enum is similar to {@link com.ibm.icu.text.MeasureFormat.FormatWidth}.
*
* @draft ICU 60

View file

@ -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<String> EQUIVALENT_CURRENCY_SYMBOLS =
new EquivalenceRelation<String>()
.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);
}
}
/**

View file

@ -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));
}
}

View file

@ -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!"},

View file

@ -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)",