// Tag for localized display names (symbols) of currencies
static const char CURRENCIES[] = "Currencies";
static const char CURRENCIES_NARROW[] = "Currencies%narrow";
+static const char CURRENCIES_FORMAL[] = "Currencies%formal";
+static const char CURRENCIES_VARIANT[] = "Currencies%variant";
static const char CURRENCYPLURALS[] = "CurrencyPlurals";
// ISO codes mapping table
}
int32_t choice = (int32_t) nameStyle;
- if (choice < 0 || choice > 2) {
+ if (choice < 0 || choice > 4) {
*ec = U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
ec2 = U_ZERO_ERROR;
LocalUResourceBundlePointer rb(ures_open(U_ICUDATA_CURR, loc, &ec2));
- if (nameStyle == UCURR_NARROW_SYMBOL_NAME) {
+ if (nameStyle == UCURR_NARROW_SYMBOL_NAME || nameStyle == UCURR_FORMAL_SYMBOL_NAME || nameStyle == UCURR_VARIANT_SYMBOL_NAME) {
CharString key;
- key.append(CURRENCIES_NARROW, ec2);
+ switch (nameStyle) {
+ case UCURR_NARROW_SYMBOL_NAME:
+ key.append(CURRENCIES_NARROW, ec2);
+ break;
+ case UCURR_FORMAL_SYMBOL_NAME:
+ key.append(CURRENCIES_FORMAL, ec2);
+ break;
+ case UCURR_VARIANT_SYMBOL_NAME:
+ key.append(CURRENCIES_VARIANT, ec2);
+ break;
+ default:
+ *ec = U_UNSUPPORTED_ERROR;
+ return 0;
+ }
key.append("/", ec2);
key.append(buf, ec2);
s = ures_getStringByKeyWithFallback(rb.getAlias(), key.data(), len, &ec2);
*
* @stable ICU 61
*/
- UCURR_NARROW_SYMBOL_NAME
+ UCURR_NARROW_SYMBOL_NAME,
+
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * Selector for getName() indicating the formal currency symbol.
+ * The formal currency symbol is similar to the regular currency
+ * symbol, but it always takes the form used in formal settings
+ * such as banking; for example, "NT$" instead of "$" for TWD in zh-TW.
+ *
+ * @draft ICU 68
+ */
+ UCURR_FORMAL_SYMBOL_NAME,
+
+ /**
+ * Selector for getName() indicating the variant currency symbol.
+ * The variant symbol for a currency is an alternative symbol
+ * that is not necessarily as widely used as the regular symbol.
+ *
+ * @draft ICU 68
+ */
+ UCURR_VARIANT_SYMBOL_NAME
+#endif // U_HIDE_DRAFT_API
+
} UCurrNameStyle;
#if !UCONFIG_NO_SERVICE
return loadSymbol(UCURR_NARROW_SYMBOL_NAME, status);
}
+UnicodeString CurrencySymbols::getFormalCurrencySymbol(UErrorCode& status) const {
+ // Note: currently no override is available for formal currency symbol
+ return loadSymbol(UCURR_FORMAL_SYMBOL_NAME, status);
+}
+
+UnicodeString CurrencySymbols::getVariantCurrencySymbol(UErrorCode& status) const {
+ // Note: currently no override is available for variant currency symbol
+ return loadSymbol(UCURR_VARIANT_SYMBOL_NAME, status);
+}
+
UnicodeString CurrencySymbols::getCurrencySymbol(UErrorCode& status) const {
if (!fCurrencySymbol.isBogus()) {
return fCurrencySymbol;
UnicodeString getNarrowCurrencySymbol(UErrorCode& status) const;
+ UnicodeString getFormalCurrencySymbol(UErrorCode& status) const;
+
+ UnicodeString getVariantCurrencySymbol(UErrorCode& status) const;
+
UnicodeString getCurrencySymbol(UErrorCode& status) const;
UnicodeString getIntlCurrencySymbol(UErrorCode& status) const;
case AffixPatternType::TYPE_PERMILLE:
return fSymbols->getSymbol(DecimalFormatSymbols::ENumberFormatSymbol::kPerMillSymbol);
case AffixPatternType::TYPE_CURRENCY_SINGLE: {
- // UnitWidth ISO and HIDDEN overrides the singular currency symbol.
- if (fUnitWidth == UNumberUnitWidth::UNUM_UNIT_WIDTH_ISO_CODE) {
+ switch (fUnitWidth) {
+ case UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW:
+ return fCurrencySymbols.getNarrowCurrencySymbol(localStatus);
+ case UNumberUnitWidth::UNUM_UNIT_WIDTH_SHORT:
+ return fCurrencySymbols.getCurrencySymbol(localStatus);
+ case UNumberUnitWidth::UNUM_UNIT_WIDTH_ISO_CODE:
return fCurrencySymbols.getIntlCurrencySymbol(localStatus);
- } else if (fUnitWidth == UNumberUnitWidth::UNUM_UNIT_WIDTH_HIDDEN) {
+ case UNumberUnitWidth::UNUM_UNIT_WIDTH_FORMAL:
+ return fCurrencySymbols.getFormalCurrencySymbol(localStatus);
+ case UNumberUnitWidth::UNUM_UNIT_WIDTH_VARIANT:
+ return fCurrencySymbols.getVariantCurrencySymbol(localStatus);
+ case UNumberUnitWidth::UNUM_UNIT_WIDTH_HIDDEN:
return UnicodeString();
- } else if (fUnitWidth == UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW) {
- return fCurrencySymbols.getNarrowCurrencySymbol(localStatus);
- } else {
+ default:
return fCurrencySymbols.getCurrencySymbol(localStatus);
}
}
b.add(u"unit-width-short", STEM_UNIT_WIDTH_SHORT, status);
b.add(u"unit-width-full-name", STEM_UNIT_WIDTH_FULL_NAME, status);
b.add(u"unit-width-iso-code", STEM_UNIT_WIDTH_ISO_CODE, status);
+ b.add(u"unit-width-formal", STEM_UNIT_WIDTH_FORMAL, status);
+ b.add(u"unit-width-variant", STEM_UNIT_WIDTH_VARIANT, status);
b.add(u"unit-width-hidden", STEM_UNIT_WIDTH_HIDDEN, status);
b.add(u"sign-auto", STEM_SIGN_AUTO, status);
b.add(u"sign-always", STEM_SIGN_ALWAYS, status);
return UNUM_UNIT_WIDTH_FULL_NAME;
case STEM_UNIT_WIDTH_ISO_CODE:
return UNUM_UNIT_WIDTH_ISO_CODE;
+ case STEM_UNIT_WIDTH_FORMAL:
+ return UNUM_UNIT_WIDTH_FORMAL;
+ case STEM_UNIT_WIDTH_VARIANT:
+ return UNUM_UNIT_WIDTH_VARIANT;
case STEM_UNIT_WIDTH_HIDDEN:
return UNUM_UNIT_WIDTH_HIDDEN;
default:
case UNUM_UNIT_WIDTH_ISO_CODE:
sb.append(u"unit-width-iso-code", -1);
break;
+ case UNUM_UNIT_WIDTH_FORMAL:
+ sb.append(u"unit-width-formal", -1);
+ break;
+ case UNUM_UNIT_WIDTH_VARIANT:
+ sb.append(u"unit-width-variant", -1);
+ break;
case UNUM_UNIT_WIDTH_HIDDEN:
sb.append(u"unit-width-hidden", -1);
break;
case STEM_UNIT_WIDTH_SHORT:
case STEM_UNIT_WIDTH_FULL_NAME:
case STEM_UNIT_WIDTH_ISO_CODE:
+ case STEM_UNIT_WIDTH_FORMAL:
+ case STEM_UNIT_WIDTH_VARIANT:
case STEM_UNIT_WIDTH_HIDDEN:
CHECK_NULL(seen, unitWidth, status);
macros.unitWidth = stem_to_object::unitWidth(stem);
STEM_UNIT_WIDTH_SHORT,
STEM_UNIT_WIDTH_FULL_NAME,
STEM_UNIT_WIDTH_ISO_CODE,
+ STEM_UNIT_WIDTH_FORMAL,
+ STEM_UNIT_WIDTH_VARIANT,
STEM_UNIT_WIDTH_HIDDEN,
STEM_SIGN_AUTO,
STEM_SIGN_ALWAYS,
*/
UNUM_UNIT_WIDTH_ISO_CODE,
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * Use the formal variant of the currency symbol; for example, "NT$" for the New Taiwan
+ * dollar in zh-TW.
+ *
+ * <p>
+ * Behavior of this option with non-currency units is not defined at this time.
+ *
+ * @draft ICU 68
+ */
+ UNUM_UNIT_WIDTH_FORMAL,
+
+ /**
+ * Use the alternate variant of the currency symbol; for example, "TL" for the Turkish
+ * lira (TRY).
+ *
+ * <p>
+ * Behavior of this option with non-currency units is not defined at this time.
+ *
+ * @draft ICU 68
+ */
+ UNUM_UNIT_WIDTH_VARIANT,
+#endif // U_HIDE_DRAFT_API
+
/**
* Format the number according to the specified unit, but do not display the unit. For currencies, apply
* monetary symbols and formats as with SHORT, but omit the currency symbol. For measure units, the behavior is
CurrencyUnit ESP;
CurrencyUnit PTE;
CurrencyUnit RON;
+ CurrencyUnit TWD;
+ CurrencyUnit TRY;
CurrencyUnit CNY;
MeasureUnit METER;
ESP(u"ESP", status),
PTE(u"PTE", status),
RON(u"RON", status),
+ TWD(u"TWD", status),
+ TRY(u"TRY", status),
CNY(u"CNY", status),
FRENCH_SYMBOLS(Locale::getFrench(), status),
SWISS_SYMBOLS(Locale("de-CH"), status),
5.43,
u"US$5.43");
+ assertFormatSingle(
+ u"Currency Difference between Formal and Short (Formal Version)",
+ u"currency/TWD unit-width-formal",
+ u"currency/TWD unit-width-formal",
+ NumberFormatter::with().unit(TWD).unitWidth(UNUM_UNIT_WIDTH_FORMAL),
+ Locale("zh-TW"),
+ 5.43,
+ u"NT$5.43");
+
+ assertFormatSingle(
+ u"Currency Difference between Formal and Short (Short Version)",
+ u"currency/TWD unit-width-short",
+ u"currency/TWD unit-width-short",
+ NumberFormatter::with().unit(TWD).unitWidth(UNUM_UNIT_WIDTH_SHORT),
+ Locale("zh-TW"),
+ 5.43,
+ u"$5.43");
+
+ assertFormatSingle(
+ u"Currency Difference between Variant and Short (Formal Version)",
+ u"currency/TRY unit-width-variant",
+ u"currency/TRY unit-width-variant",
+ NumberFormatter::with().unit(TRY).unitWidth(UNUM_UNIT_WIDTH_VARIANT),
+ Locale("tr-TR"),
+ 5.43,
+ u"TL\u00A05,43");
+
+ assertFormatSingle(
+ u"Currency Difference between Variant and Short (Short Version)",
+ u"currency/TRY unit-width-short",
+ u"currency/TRY unit-width-short",
+ NumberFormatter::with().unit(TRY).unitWidth(UNUM_UNIT_WIDTH_SHORT),
+ Locale("tr-TR"),
+ 5.43,
+ u"₺5,43");
+
assertFormatSingle(
u"Currency-dependent format (Control)",
u"currency/USD unit-width-short",
TESTCASE_AUTO(TestCases);
TESTCASE_AUTO(TestCurrencyNames);
- TESTCASE_AUTO(Test20484_NarrowSymbolFallback);
+ TESTCASE_AUTO(TestCurrencyVariants);
TESTCASE_AUTO(TestCurrencyAmount);
TESTCASE_AUTO(TestCurrencyUnit);
TESTCASE_AUTO(TestCoverage);
// TODO add more tests later
}
-void NumberFormatTest::Test20484_NarrowSymbolFallback(){
- IcuTestErrorCode status(*this, "Test20484_NarrowSymbolFallback");
+void NumberFormatTest::TestCurrencyVariants(){
+ IcuTestErrorCode status(*this, "TestCurrencyVariants");
struct TestCase {
const char* locale;
const char16_t* isoCode;
const char16_t* expectedShort;
const char16_t* expectedNarrow;
+ const char16_t* expectedFormal;
+ const char16_t* expectedVariant;
UErrorCode expectedNarrowError;
} cases[] = {
- {"en-US", u"CAD", u"CA$", u"$", U_USING_DEFAULT_WARNING}, // narrow: fallback to root
- {"en-US", u"CDF", u"CDF", u"CDF", U_USING_FALLBACK_WARNING}, // narrow: fallback to short
- {"sw-CD", u"CDF", u"FC", u"FC", U_USING_FALLBACK_WARNING}, // narrow: fallback to short
- {"en-US", u"GEL", u"GEL", u"₾", U_USING_DEFAULT_WARNING}, // narrow: fallback to root
- {"ka-GE", u"GEL", u"₾", u"₾", U_USING_FALLBACK_WARNING}, // narrow: fallback to ka
- {"ka", u"GEL", u"₾", u"₾", U_ZERO_ERROR}, // no fallback on narrow
+ {"en-US", u"CAD", u"CA$", u"$", u"CA$", u"CA$", U_USING_DEFAULT_WARNING}, // narrow: fallback to root
+ {"en-US", u"CDF", u"CDF", u"CDF", u"CDF", u"CDF", U_USING_FALLBACK_WARNING}, // narrow: fallback to short
+ {"sw-CD", u"CDF", u"FC", u"FC", u"FC", u"FC", U_USING_FALLBACK_WARNING}, // narrow: fallback to short
+ {"en-US", u"GEL", u"GEL", u"₾", u"GEL", u"GEL", U_USING_DEFAULT_WARNING}, // narrow: fallback to root
+ {"ka-GE", u"GEL", u"₾", u"₾", u"₾", u"₾", U_USING_FALLBACK_WARNING}, // narrow: fallback to ka
+ {"ka", u"GEL", u"₾", u"₾", u"₾", u"₾", U_ZERO_ERROR}, // no fallback on narrow
+ {"zh-TW", u"TWD", u"$", u"$", u"NT$", u"$", U_USING_FALLBACK_WARNING}, // narrow: fallback to short
+ {"ccp", u"TRY", u"TRY", u"₺", u"TRY", u"TL", U_ZERO_ERROR}, // no fallback on variant
};
for (const auto& cas : cases) {
status.setScope(cas.isoCode);
&choiceFormatIgnored,
&lengthIgnored,
status);
+ const UChar* actualFormal = ucurr_getName(
+ cas.isoCode,
+ cas.locale,
+ UCURR_FORMAL_SYMBOL_NAME,
+ &choiceFormatIgnored,
+ &lengthIgnored,
+ status);
+ const UChar* actualVarant = ucurr_getName(
+ cas.isoCode,
+ cas.locale,
+ UCURR_VARIANT_SYMBOL_NAME,
+ &choiceFormatIgnored,
+ &lengthIgnored,
+ status);
status.errIfFailureAndReset();
const UChar* actualNarrow = ucurr_getName(
cas.isoCode,
status.expectErrorAndReset(cas.expectedNarrowError);
assertEquals(UnicodeString("Short symbol: ") + cas.locale + u": " + cas.isoCode,
cas.expectedShort, actualShort);
- assertEquals(UnicodeString("Narrow symbol: ") + cas.locale + ": " + cas.isoCode,
+ assertEquals(UnicodeString("Narrow symbol: ") + cas.locale + u": " + cas.isoCode,
cas.expectedNarrow, actualNarrow);
+ assertEquals(UnicodeString("Formal symbol: ") + cas.locale + u": " + cas.isoCode,
+ cas.expectedFormal, actualFormal);
+ assertEquals(UnicodeString("Variant symbol: ") + cas.locale + u": " + cas.isoCode,
+ cas.expectedVariant, actualVarant);
}
}
void TestCurrencyNames(void);
- void Test20484_NarrowSymbolFallback(void);
+ void TestCurrencyVariants(void);
void TestCurrencyAmount(void);