mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-08 06:53:45 +00:00
ICU-20577 Restore C MeasureFormat ability to adopt non-decimal number formatter (#789)
This commit is contained in:
parent
7237fc58b4
commit
0801dd0bdd
4 changed files with 83 additions and 3 deletions
|
@ -685,9 +685,19 @@ UnicodeString &MeasureFormat::formatMeasure(
|
|||
}
|
||||
auto* df = dynamic_cast<const DecimalFormat*>(&nf);
|
||||
if (df == nullptr) {
|
||||
// Don't know how to handle other types of NumberFormat
|
||||
status = U_UNSUPPORTED_ERROR;
|
||||
return appendTo;
|
||||
// Handle other types of NumberFormat using the ICU 63 code, modified to
|
||||
// get the unitPattern from LongNameHandler and handle fallback to OTHER.
|
||||
UnicodeString formattedNumber;
|
||||
StandardPlural::Form pluralForm = QuantityFormatter::selectPlural(
|
||||
amtNumber, nf, **pluralRules, formattedNumber, pos, status);
|
||||
UnicodeString pattern = number::impl::LongNameHandler::getUnitPattern(getLocale(status),
|
||||
amtUnit, getUnitWidth(fWidth), pluralForm, status);
|
||||
// The above handles fallback from other widths to short, and from other plural forms to OTHER
|
||||
if (U_FAILURE(status)) {
|
||||
return appendTo;
|
||||
}
|
||||
SimpleFormatter formatter(pattern, 0, 1, status);
|
||||
return QuantityFormatter::format(formatter, formattedNumber, appendTo, pos, status);
|
||||
}
|
||||
number::FormattedNumber result;
|
||||
if (auto* lnf = df->toNumberFormatter(status)) {
|
||||
|
|
|
@ -264,6 +264,26 @@ UnicodeString LongNameHandler::getUnitDisplayName(
|
|||
return simpleFormats[DNAM_INDEX];
|
||||
}
|
||||
|
||||
UnicodeString LongNameHandler::getUnitPattern(
|
||||
const Locale& loc,
|
||||
const MeasureUnit& unit,
|
||||
UNumberUnitWidth width,
|
||||
StandardPlural::Form pluralForm,
|
||||
UErrorCode& status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return ICU_Utility::makeBogusString();
|
||||
}
|
||||
UnicodeString simpleFormats[ARRAY_LENGTH];
|
||||
getMeasureData(loc, unit, width, simpleFormats, status);
|
||||
// The above already handles fallback from other widths to short
|
||||
if (U_FAILURE(status)) {
|
||||
return ICU_Utility::makeBogusString();
|
||||
}
|
||||
// Now handle fallback from other plural forms to OTHER
|
||||
return (!(simpleFormats[pluralForm]).isBogus())? simpleFormats[pluralForm]:
|
||||
simpleFormats[StandardPlural::Form::OTHER];
|
||||
}
|
||||
|
||||
LongNameHandler* LongNameHandler::forCurrencyLongNames(const Locale &loc, const CurrencyUnit ¤cy,
|
||||
const PluralRules *rules,
|
||||
const MicroPropsGenerator *parent,
|
||||
|
|
|
@ -22,6 +22,13 @@ class LongNameHandler : public MicroPropsGenerator, public ModifierStore, public
|
|||
UNumberUnitWidth width,
|
||||
UErrorCode& status);
|
||||
|
||||
static UnicodeString getUnitPattern(
|
||||
const Locale& loc,
|
||||
const MeasureUnit& unit,
|
||||
UNumberUnitWidth width,
|
||||
StandardPlural::Form pluralForm,
|
||||
UErrorCode& status);
|
||||
|
||||
static LongNameHandler*
|
||||
forCurrencyLongNames(const Locale &loc, const CurrencyUnit ¤cy, const PluralRules *rules,
|
||||
const MicroPropsGenerator *parent, UErrorCode &status);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "charstr.h"
|
||||
#include "cstr.h"
|
||||
#include "unicode/reldatefmt.h"
|
||||
#include "unicode/rbnf.h"
|
||||
|
||||
struct ExpectedResult {
|
||||
const Measure *measures;
|
||||
|
@ -1699,6 +1700,10 @@ void MeasureFormatTest::TestExamplesInDocs() {
|
|||
|
||||
void MeasureFormatTest::TestFormatPeriodEn() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
Measure t_1y[] = {Measure((double)1, MeasureUnit::createYear(status), status)};
|
||||
Measure t_5M[] = {Measure((double)5, MeasureUnit::createMonth(status), status)};
|
||||
Measure t_4d[] = {Measure((double)4, MeasureUnit::createDay(status), status)};
|
||||
Measure t_2h[] = {Measure((double)2, MeasureUnit::createHour(status), status)};
|
||||
Measure t_19m[] = {Measure((double)19, MeasureUnit::createMinute(status), status)};
|
||||
Measure t_1h_23_5s[] = {
|
||||
Measure((double)1.0, MeasureUnit::createHour(status), status),
|
||||
|
@ -1867,6 +1872,20 @@ void MeasureFormatTest::TestFormatPeriodEn() {
|
|||
{t_6h_56_92m, UPRV_LENGTHOF(t_6h_56_92m), "6:56.92"},
|
||||
{t_3h_5h, UPRV_LENGTHOF(t_3h_5h), "3 \\u0998\\u0983, 5 \\u0998\\u0983"}};
|
||||
|
||||
ExpectedResult fullDataSpellout[] = {
|
||||
{t_1y, UPRV_LENGTHOF(t_1y), "one year"},
|
||||
{t_5M, UPRV_LENGTHOF(t_5M), "five months"},
|
||||
{t_4d, UPRV_LENGTHOF(t_4d), "four days"},
|
||||
{t_2h, UPRV_LENGTHOF(t_2h), "two hours"},
|
||||
{t_19m, UPRV_LENGTHOF(t_19m), "nineteen minutes"}};
|
||||
|
||||
ExpectedResult fullDataSpelloutFr[] = {
|
||||
{t_1y, UPRV_LENGTHOF(t_1y), "un\\u00A0an"},
|
||||
{t_5M, UPRV_LENGTHOF(t_5M), "cinq\\u00A0mois"},
|
||||
{t_4d, UPRV_LENGTHOF(t_4d), "quatre\\u00A0jours"},
|
||||
{t_2h, UPRV_LENGTHOF(t_2h), "deux\\u00A0heures"},
|
||||
{t_19m, UPRV_LENGTHOF(t_19m), "dix-neuf minutes"}};
|
||||
|
||||
Locale en(Locale::getEnglish());
|
||||
LocalPointer<NumberFormat> nf(NumberFormat::createInstance(en, status));
|
||||
if (U_FAILURE(status)) {
|
||||
|
@ -1947,6 +1966,30 @@ void MeasureFormatTest::TestFormatPeriodEn() {
|
|||
return;
|
||||
}
|
||||
verifyFormat("bn-u-nu-latn NUMERIC", mf, numericDataBnLatn, UPRV_LENGTHOF(numericDataBnLatn));
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
LocalPointer<RuleBasedNumberFormat> rbnf(new RuleBasedNumberFormat(URBNF_SPELLOUT, en, status));
|
||||
if (U_FAILURE(status)) {
|
||||
dataerrln("Error creating rbnf en object - %s", u_errorName(status));
|
||||
return;
|
||||
}
|
||||
mf = MeasureFormat(en, UMEASFMT_WIDTH_WIDE, rbnf->clone(), status);
|
||||
if (!assertSuccess("Error creating measure format en WIDE with rbnf", status)) {
|
||||
return;
|
||||
}
|
||||
verifyFormat("en WIDE rbnf", mf, fullDataSpellout, UPRV_LENGTHOF(fullDataSpellout));
|
||||
|
||||
Locale fr(Locale::getFrench());
|
||||
LocalPointer<RuleBasedNumberFormat> rbnffr(new RuleBasedNumberFormat(URBNF_SPELLOUT, fr, status));
|
||||
if (U_FAILURE(status)) {
|
||||
dataerrln("Error creating rbnf fr object - %s", u_errorName(status));
|
||||
return;
|
||||
}
|
||||
mf = MeasureFormat(fr, UMEASFMT_WIDTH_WIDE, rbnffr->clone(), status);
|
||||
if (!assertSuccess("Error creating measure format fr WIDE with rbnf", status)) {
|
||||
return;
|
||||
}
|
||||
verifyFormat("fr WIDE rbnf", mf, fullDataSpelloutFr, UPRV_LENGTHOF(fullDataSpellout));
|
||||
}
|
||||
|
||||
void MeasureFormatTest::Test10219FractionalPlurals() {
|
||||
|
|
Loading…
Add table
Reference in a new issue