void RelativeDateTimeFormatterTest::TestCustomNumberFormat() { NumberFormat *nf; UErrorCode status = U_ZERO_ERROR; { RelativeDateTimeFormatter fmt("en", status); if (U_FAILURE(status)) { dataerrln( "Failure creating format object - %s", u_errorName(status)); return; } nf = (NumberFormat *) fmt.getNumberFormat().clone(); } nf->setMinimumFractionDigits(1); nf->setMaximumFractionDigits(1); RelativeDateTimeFormatter fmt("en", nf, status); // Test copy constructor. RelativeDateTimeFormatter fmt2(fmt); RunTest(fmt2, kEnglishDecimal, UPRV_LENGTHOF(kEnglishDecimal), "en decimal digits"); // Test assignment fmt = RelativeDateTimeFormatter("es", status); RunTest(fmt, kSpanishNoQuantity, UPRV_LENGTHOF(kSpanishNoQuantity), "assignment operator"); }
/** * This test does round-trip testing (format -> parse -> format -> parse -> etc.) of * NumberFormat. */ void IntlTestNumberFormatAPI::testAPI(/* char* par */) { UErrorCode status = U_ZERO_ERROR; // ======= Test constructors logln("Testing NumberFormat constructors"); NumberFormat *def = NumberFormat::createInstance(status); if(U_FAILURE(status)) { errln("ERROR: Could not create NumberFormat (default)"); } status = U_ZERO_ERROR; NumberFormat *fr = NumberFormat::createInstance(Locale::getFrench(), status); if(U_FAILURE(status)) { errln("ERROR: Could not create NumberFormat (French)"); } NumberFormat *cur = NumberFormat::createCurrencyInstance(status); if(U_FAILURE(status)) { errln("ERROR: Could not create NumberFormat (currency, default)"); } status = U_ZERO_ERROR; NumberFormat *cur_fr = NumberFormat::createCurrencyInstance(Locale::getFrench(), status); if(U_FAILURE(status)) { errln("ERROR: Could not create NumberFormat (currency, French)"); } NumberFormat *per = NumberFormat::createPercentInstance(status); if(U_FAILURE(status)) { errln("ERROR: Could not create NumberFormat (percent, default)"); } status = U_ZERO_ERROR; NumberFormat *per_fr = NumberFormat::createPercentInstance(Locale::getFrench(), status); if(U_FAILURE(status)) { errln("ERROR: Could not create NumberFormat (percent, French)"); } // ======= Test equality if (per_fr != NULL && cur_fr != NULL) { logln("Testing equality operator"); if( *per_fr == *cur_fr || ! ( *per_fr != *cur_fr) ) { errln("ERROR: == failed"); } } // ======= Test various format() methods if (cur_fr != NULL) { logln("Testing various format() methods"); double d = -10456.0037; int32_t l = 100000000; Formattable fD(d); Formattable fL(l); UnicodeString res1, res2, res3, res4, res5, res6; FieldPosition pos1(0), pos2(0), pos3(0), pos4(0); res1 = cur_fr->format(d, res1); logln( (UnicodeString) "" + (int32_t) d + " formatted to " + res1); res2 = cur_fr->format(l, res2); logln((UnicodeString) "" + (int32_t) l + " formatted to " + res2); res3 = cur_fr->format(d, res3, pos1); logln( (UnicodeString) "" + (int32_t) d + " formatted to " + res3); res4 = cur_fr->format(l, res4, pos2); logln((UnicodeString) "" + (int32_t) l + " formatted to " + res4); status = U_ZERO_ERROR; res5 = cur_fr->format(fD, res5, pos3, status); if(U_FAILURE(status)) { errln("ERROR: format(Formattable [double]) failed"); } logln((UnicodeString) "" + (int32_t) fD.getDouble() + " formatted to " + res5); status = U_ZERO_ERROR; res6 = cur_fr->format(fL, res6, pos4, status); if(U_FAILURE(status)) { errln("ERROR: format(Formattable [long]) failed"); } logln((UnicodeString) "" + fL.getLong() + " formatted to " + res6); } // ======= Test parse() if (fr != NULL) { logln("Testing parse()"); double d = -10456.0037; UnicodeString text("-10,456.0037"); Formattable result1, result2, result3; ParsePosition pos(0), pos01(0); fr->parseObject(text, result1, pos); if(result1.getType() != Formattable::kDouble && result1.getDouble() != d) { errln("ERROR: Roundtrip failed (via parse()) for " + text); } logln(text + " parsed into " + (int32_t) result1.getDouble()); fr->parse(text, result2, pos01); if(result2.getType() != Formattable::kDouble && result2.getDouble() != d) { errln("ERROR: Roundtrip failed (via parse()) for " + text); } logln(text + " parsed into " + (int32_t) result2.getDouble()); status = U_ZERO_ERROR; fr->parse(text, result3, status); if(U_FAILURE(status)) { errln("ERROR: parse() failed"); } if(result3.getType() != Formattable::kDouble && result3.getDouble() != d) { errln("ERROR: Roundtrip failed (via parse()) for " + text); } logln(text + " parsed into " + (int32_t) result3.getDouble()); } // ======= Test getters and setters if (fr != NULL && def != NULL) { logln("Testing getters and setters"); int32_t count = 0; const Locale *locales = NumberFormat::getAvailableLocales(count); logln((UnicodeString) "Got " + count + " locales" ); for(int32_t i = 0; i < count; i++) { UnicodeString name(locales[i].getName(),""); logln(name); } fr->setParseIntegerOnly( def->isParseIntegerOnly() ); if(fr->isParseIntegerOnly() != def->isParseIntegerOnly() ) { errln("ERROR: setParseIntegerOnly() failed"); } fr->setGroupingUsed( def->isGroupingUsed() ); if(fr->isGroupingUsed() != def->isGroupingUsed() ) { errln("ERROR: setGroupingUsed() failed"); } fr->setMaximumIntegerDigits( def->getMaximumIntegerDigits() ); if(fr->getMaximumIntegerDigits() != def->getMaximumIntegerDigits() ) { errln("ERROR: setMaximumIntegerDigits() failed"); } fr->setMinimumIntegerDigits( def->getMinimumIntegerDigits() ); if(fr->getMinimumIntegerDigits() != def->getMinimumIntegerDigits() ) { errln("ERROR: setMinimumIntegerDigits() failed"); } fr->setMaximumFractionDigits( def->getMaximumFractionDigits() ); if(fr->getMaximumFractionDigits() != def->getMaximumFractionDigits() ) { errln("ERROR: setMaximumFractionDigits() failed"); } fr->setMinimumFractionDigits( def->getMinimumFractionDigits() ); if(fr->getMinimumFractionDigits() != def->getMinimumFractionDigits() ) { errln("ERROR: setMinimumFractionDigits() failed"); } } // ======= Test getStaticClassID() logln("Testing getStaticClassID()"); status = U_ZERO_ERROR; NumberFormat *test = new DecimalFormat(status); if(U_FAILURE(status)) { errln("ERROR: Couldn't create a NumberFormat"); } if(test->getDynamicClassID() != DecimalFormat::getStaticClassID()) { errln("ERROR: getDynamicClassID() didn't return the expected value"); } delete test; delete def; delete fr; delete cur; delete cur_fr; delete per; delete per_fr; }
/* * Set a currency on a NumberFormat with pre-ICU 2.6 APIs. * This is a "hack" that will not work properly for all cases because * only ICU 2.6 introduced a more complete framework and data for this. * * @param nf The NumberFormat on which to set the currency; takes effect on * currency-formatting NumberFormat instances. * This must actually be a DecimalFormat instance. * The display style of the output is controlled by nf (its pattern, * usually from the display locale ID used to create this instance) * while the currency symbol and number of decimals are set for * the currency. * @param currency The 3-letter ISO 4217 currency code, NUL-terminated. * @param errorCode ICU error code, must pass U_SUCCESS() on input. */ static void setNumberFormatCurrency_2_4(NumberFormat &nf, const char *currency, UErrorCode &errorCode) { // argument checking if(U_FAILURE(errorCode)) { return; } if(currency==NULL || strlen(currency)!=3) { errorCode=U_ILLEGAL_ARGUMENT_ERROR; return; } // check that the formatter is a DecimalFormat instance // necessary because we will cast to the DecimalFormat subclass to set // the currency symbol DecimalFormat *dnf=dynamic_cast<DecimalFormat *>(&nf); if(dnf==NULL) { errorCode=U_ILLEGAL_ARGUMENT_ERROR; return; } // map the currency code to a locale ID // only the currencies in this array are supported // it would be possible to map to a locale ID, instantiate a currency // formatter for that and copy its values, but that would be slower, // and we have to hardcode something here anyway static const struct { // ISO currency ID const char *currency; // fractionDigits==minimumFractionDigits==maximumFractionDigits // for these currencies int32_t fractionDigits; /* * Set the rounding increment to 0 if it is implied with the number of * fraction digits. Setting an explicit rounding increment makes * number formatting slower. * In other words, set it to something other than 0 only for unusual * cases like "nickel rounding" (0.05) when the increment differs from * 10^(-maximumFractionDigits). */ double roundingIncrement; // Unicode string with the desired currency display symbol or name UChar symbol[16]; } currencyMap[]={ { "USD", 2, 0.0, { 0x24, 0 } }, { "GBP", 2, 0.0, { 0xa3, 0 } }, { "EUR", 2, 0.0, { 0x20ac, 0 } }, { "JPY", 0, 0.0, { 0xa5, 0 } } }; int32_t i; for(i=0; i<UPRV_LENGTHOF(currencyMap); ++i) { if(strcmp(currency, currencyMap[i].currency)==0) { break; } } if(i==UPRV_LENGTHOF(currencyMap)) { // a more specific error code would be useful in a real application errorCode=U_UNSUPPORTED_ERROR; return; } // set the currency-related data into the caller's formatter nf.setMinimumFractionDigits(currencyMap[i].fractionDigits); nf.setMaximumFractionDigits(currencyMap[i].fractionDigits); dnf->setRoundingIncrement(currencyMap[i].roundingIncrement); DecimalFormatSymbols symbols(*dnf->getDecimalFormatSymbols()); symbols.setSymbol(DecimalFormatSymbols::kCurrencySymbol, currencyMap[i].symbol); dnf->setDecimalFormatSymbols(symbols); // do not adopt symbols: Jitterbug 2889 }