19596a2c1Sopenharmony_ci/* 29596a2c1Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 39596a2c1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 49596a2c1Sopenharmony_ci * you may not use this file except in compliance with the License. 59596a2c1Sopenharmony_ci * You may obtain a copy of the License at 69596a2c1Sopenharmony_ci * 79596a2c1Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 89596a2c1Sopenharmony_ci * 99596a2c1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 109596a2c1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 119596a2c1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 129596a2c1Sopenharmony_ci * See the License for the specific language governing permissions and 139596a2c1Sopenharmony_ci * limitations under the License. 149596a2c1Sopenharmony_ci */ 159596a2c1Sopenharmony_ci#include "locale_config.h" 169596a2c1Sopenharmony_ci 179596a2c1Sopenharmony_ci#include <cctype> 189596a2c1Sopenharmony_ci#include <sstream> 199596a2c1Sopenharmony_ci#include "i18n_hilog.h" 209596a2c1Sopenharmony_ci#include "ohos/init_data.h" 219596a2c1Sopenharmony_ci#include "parameter.h" 229596a2c1Sopenharmony_ci#include "unicode/ucurr.h" 239596a2c1Sopenharmony_ci#include "unicode/uenum.h" 249596a2c1Sopenharmony_ci#include "unicode/utypes.h" 259596a2c1Sopenharmony_ci#include "utils.h" 269596a2c1Sopenharmony_ci#include "number_format.h" 279596a2c1Sopenharmony_ci 289596a2c1Sopenharmony_cinamespace OHOS { 299596a2c1Sopenharmony_cinamespace Global { 309596a2c1Sopenharmony_cinamespace I18n { 319596a2c1Sopenharmony_ciconst char* NumberFormat::DEVICE_TYPE_NAME = "const.product.devicetype"; 329596a2c1Sopenharmony_cistd::unordered_map<std::string, std::string> NumberFormat::numToCurrency = {}; 339596a2c1Sopenharmony_cibool NumberFormat::icuInitialized = NumberFormat::Init(); 349596a2c1Sopenharmony_ci 359596a2c1Sopenharmony_cistd::unordered_map<std::string, UNumberUnitWidth> NumberFormat::unitStyle = { 369596a2c1Sopenharmony_ci { "long", UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME }, 379596a2c1Sopenharmony_ci { "short", UNumberUnitWidth::UNUM_UNIT_WIDTH_SHORT }, 389596a2c1Sopenharmony_ci { "narrow", UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW } 399596a2c1Sopenharmony_ci}; 409596a2c1Sopenharmony_ci 419596a2c1Sopenharmony_cistd::unordered_map<std::string, UNumberUnitWidth> NumberFormat::currencyStyle = { 429596a2c1Sopenharmony_ci { "symbol", UNumberUnitWidth::UNUM_UNIT_WIDTH_SHORT }, 439596a2c1Sopenharmony_ci { "code", UNumberUnitWidth::UNUM_UNIT_WIDTH_ISO_CODE }, 449596a2c1Sopenharmony_ci { "name", UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME }, 459596a2c1Sopenharmony_ci { "narrowSymbol", UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW } 469596a2c1Sopenharmony_ci}; 479596a2c1Sopenharmony_ci 489596a2c1Sopenharmony_cistd::unordered_map<std::string, UNumberSignDisplay> NumberFormat::signAutoStyle = { 499596a2c1Sopenharmony_ci { "auto", UNumberSignDisplay::UNUM_SIGN_AUTO }, 509596a2c1Sopenharmony_ci { "never", UNumberSignDisplay::UNUM_SIGN_NEVER }, 519596a2c1Sopenharmony_ci { "always", UNumberSignDisplay::UNUM_SIGN_ALWAYS }, 529596a2c1Sopenharmony_ci { "exceptZero", UNumberSignDisplay::UNUM_SIGN_EXCEPT_ZERO } 539596a2c1Sopenharmony_ci}; 549596a2c1Sopenharmony_ci 559596a2c1Sopenharmony_cistd::unordered_map<std::string, UNumberSignDisplay> NumberFormat::signAccountingStyle = { 569596a2c1Sopenharmony_ci { "auto", UNumberSignDisplay::UNUM_SIGN_ACCOUNTING }, 579596a2c1Sopenharmony_ci { "never", UNumberSignDisplay::UNUM_SIGN_NEVER }, 589596a2c1Sopenharmony_ci { "always", UNumberSignDisplay::UNUM_SIGN_ACCOUNTING_ALWAYS }, 599596a2c1Sopenharmony_ci { "exceptZero", UNumberSignDisplay::UNUM_SIGN_ACCOUNTING_EXCEPT_ZERO } 609596a2c1Sopenharmony_ci}; 619596a2c1Sopenharmony_ci 629596a2c1Sopenharmony_cistd::unordered_map<UMeasurementSystem, std::string> NumberFormat::measurementSystem = { 639596a2c1Sopenharmony_ci { UMeasurementSystem::UMS_SI, "SI" }, 649596a2c1Sopenharmony_ci { UMeasurementSystem::UMS_US, "US" }, 659596a2c1Sopenharmony_ci { UMeasurementSystem::UMS_UK, "UK" }, 669596a2c1Sopenharmony_ci}; 679596a2c1Sopenharmony_ci 689596a2c1Sopenharmony_cistd::unordered_map<std::string, UNumberUnitWidth> NumberFormat::defaultUnitStyle = { 699596a2c1Sopenharmony_ci { "tablet", UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME }, 709596a2c1Sopenharmony_ci { "2in1", UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME }, 719596a2c1Sopenharmony_ci { "tv", UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME }, 729596a2c1Sopenharmony_ci { "pc", UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME }, 739596a2c1Sopenharmony_ci { "wearable", UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW }, 749596a2c1Sopenharmony_ci { "liteWearable", UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW }, 759596a2c1Sopenharmony_ci { "watch", UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW } 769596a2c1Sopenharmony_ci}; 779596a2c1Sopenharmony_ci 789596a2c1Sopenharmony_cistd::unordered_map<std::string, UNumberUnitWidth> NumberFormat::defaultCurrencyStyle = { 799596a2c1Sopenharmony_ci { "wearable", UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW }, 809596a2c1Sopenharmony_ci { "liteWearable", UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW }, 819596a2c1Sopenharmony_ci { "watch", UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW } 829596a2c1Sopenharmony_ci}; 839596a2c1Sopenharmony_ci 849596a2c1Sopenharmony_cistd::map<std::string, std::string> NumberFormat::RelativeTimeFormatConfigs = { 859596a2c1Sopenharmony_ci { "numeric", "auto" } 869596a2c1Sopenharmony_ci}; 879596a2c1Sopenharmony_ci 889596a2c1Sopenharmony_ciNumberFormat::NumberFormat(const std::vector<std::string> &localeTags, std::map<std::string, std::string> &configs) 899596a2c1Sopenharmony_ci{ 909596a2c1Sopenharmony_ci SetDefaultStyle(); 919596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 929596a2c1Sopenharmony_ci std::unique_ptr<icu::LocaleBuilder> builder = nullptr; 939596a2c1Sopenharmony_ci builder = std::make_unique<icu::LocaleBuilder>(); 949596a2c1Sopenharmony_ci ParseConfigs(configs); 959596a2c1Sopenharmony_ci for (size_t i = 0; i < localeTags.size(); i++) { 969596a2c1Sopenharmony_ci std::string curLocale = localeTags[i]; 979596a2c1Sopenharmony_ci locale = icu::Locale::forLanguageTag(icu::StringPiece(curLocale), status); 989596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 999596a2c1Sopenharmony_ci status = U_ZERO_ERROR; 1009596a2c1Sopenharmony_ci continue; 1019596a2c1Sopenharmony_ci } 1029596a2c1Sopenharmony_ci if (LocaleInfo::allValidLocales.count(locale.getLanguage()) > 0) { 1039596a2c1Sopenharmony_ci localeInfo = std::make_unique<LocaleInfo>(curLocale, configs); 1049596a2c1Sopenharmony_ci CreateRelativeTimeFormat(curLocale); 1059596a2c1Sopenharmony_ci if (!localeInfo->InitSuccess()) { 1069596a2c1Sopenharmony_ci continue; 1079596a2c1Sopenharmony_ci } 1089596a2c1Sopenharmony_ci locale = localeInfo->GetLocale(); 1099596a2c1Sopenharmony_ci localeBaseName = localeInfo->GetBaseName(); 1109596a2c1Sopenharmony_ci numberFormat = icu::number::NumberFormatter::withLocale(locale); 1119596a2c1Sopenharmony_ci icu::MeasureUnit::getAvailable(unitArray, MAX_UNIT_NUM, status); 1129596a2c1Sopenharmony_ci if (!U_SUCCESS(status)) { 1139596a2c1Sopenharmony_ci status = U_ZERO_ERROR; 1149596a2c1Sopenharmony_ci continue; 1159596a2c1Sopenharmony_ci } 1169596a2c1Sopenharmony_ci createSuccess = true; 1179596a2c1Sopenharmony_ci break; 1189596a2c1Sopenharmony_ci } 1199596a2c1Sopenharmony_ci } 1209596a2c1Sopenharmony_ci if (!createSuccess) { 1219596a2c1Sopenharmony_ci std::string systemLocale = LocaleConfig::GetSystemLocale(); 1229596a2c1Sopenharmony_ci localeInfo = std::make_unique<LocaleInfo>(systemLocale, configs); 1239596a2c1Sopenharmony_ci CreateRelativeTimeFormat(systemLocale); 1249596a2c1Sopenharmony_ci if (localeInfo->InitSuccess()) { 1259596a2c1Sopenharmony_ci locale = localeInfo->GetLocale(); 1269596a2c1Sopenharmony_ci localeBaseName = localeInfo->GetBaseName(); 1279596a2c1Sopenharmony_ci numberFormat = icu::number::NumberFormatter::withLocale(locale); 1289596a2c1Sopenharmony_ci icu::MeasureUnit::getAvailable(unitArray, MAX_UNIT_NUM, status); 1299596a2c1Sopenharmony_ci if (U_SUCCESS(status)) { 1309596a2c1Sopenharmony_ci createSuccess = true; 1319596a2c1Sopenharmony_ci } 1329596a2c1Sopenharmony_ci } 1339596a2c1Sopenharmony_ci } 1349596a2c1Sopenharmony_ci if (createSuccess) { 1359596a2c1Sopenharmony_ci InitProperties(); 1369596a2c1Sopenharmony_ci } 1379596a2c1Sopenharmony_ci} 1389596a2c1Sopenharmony_ci 1399596a2c1Sopenharmony_ciNumberFormat::~NumberFormat() 1409596a2c1Sopenharmony_ci{ 1419596a2c1Sopenharmony_ci} 1429596a2c1Sopenharmony_ci 1439596a2c1Sopenharmony_civoid NumberFormat::CreateRelativeTimeFormat(const std::string& locale) 1449596a2c1Sopenharmony_ci{ 1459596a2c1Sopenharmony_ci if (unitUsage == "elapsed-time-second") { 1469596a2c1Sopenharmony_ci std::vector<std::string> locales = { locale }; 1479596a2c1Sopenharmony_ci relativeTimeFormat = std::make_unique<RelativeTimeFormat>(locales, 1489596a2c1Sopenharmony_ci RelativeTimeFormatConfigs); 1499596a2c1Sopenharmony_ci } 1509596a2c1Sopenharmony_ci} 1519596a2c1Sopenharmony_ci 1529596a2c1Sopenharmony_civoid NumberFormat::InitProperties() 1539596a2c1Sopenharmony_ci{ 1549596a2c1Sopenharmony_ci if (!currency.empty()) { 1559596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 1569596a2c1Sopenharmony_ci numberFormat = 1579596a2c1Sopenharmony_ci numberFormat.unit(icu::CurrencyUnit(icu::UnicodeString(currency.c_str()).getBuffer(), status)); 1589596a2c1Sopenharmony_ci if (currencyDisplay != UNumberUnitWidth::UNUM_UNIT_WIDTH_SHORT) { 1599596a2c1Sopenharmony_ci numberFormat = numberFormat.unitWidth(currencyDisplay); 1609596a2c1Sopenharmony_ci } 1619596a2c1Sopenharmony_ci } 1629596a2c1Sopenharmony_ci if (!styleString.empty() && styleString == "percent") { 1639596a2c1Sopenharmony_ci // 2 is the power of ten 1649596a2c1Sopenharmony_ci numberFormat = numberFormat.unit(icu::NoUnit::percent()).scale(icu::number::Scale::powerOfTen(2)).precision( 1659596a2c1Sopenharmony_ci icu::number::Precision::fixedFraction(0)); 1669596a2c1Sopenharmony_ci } 1679596a2c1Sopenharmony_ci if (!styleString.empty() && styleString == "unit") { 1689596a2c1Sopenharmony_ci for (icu::MeasureUnit curUnit : unitArray) { 1699596a2c1Sopenharmony_ci if (!strcmp(curUnit.getSubtype(), unit.c_str())) { 1709596a2c1Sopenharmony_ci numberFormat = numberFormat.unit(curUnit); 1719596a2c1Sopenharmony_ci unitType = curUnit.getType(); 1729596a2c1Sopenharmony_ci } 1739596a2c1Sopenharmony_ci } 1749596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 1759596a2c1Sopenharmony_ci UMeasurementSystem measSys = ulocdata_getMeasurementSystem(localeBaseName.c_str(), &status); 1769596a2c1Sopenharmony_ci if (U_SUCCESS(status) && measSys >= 0) { 1779596a2c1Sopenharmony_ci unitMeasSys = measurementSystem[measSys]; 1789596a2c1Sopenharmony_ci } 1799596a2c1Sopenharmony_ci numberFormat = numberFormat.unitWidth(unitDisplay); 1809596a2c1Sopenharmony_ci numberFormat = numberFormat.precision(icu::number::Precision::maxFraction(DEFAULT_FRACTION_DIGITS)); 1819596a2c1Sopenharmony_ci } 1829596a2c1Sopenharmony_ci if (!useGrouping.empty()) { 1839596a2c1Sopenharmony_ci numberFormat = numberFormat.grouping((useGrouping == "true") ? 1849596a2c1Sopenharmony_ci UNumberGroupingStrategy::UNUM_GROUPING_AUTO : UNumberGroupingStrategy::UNUM_GROUPING_OFF); 1859596a2c1Sopenharmony_ci } 1869596a2c1Sopenharmony_ci if (!currencySign.empty() || !signDisplayString.empty()) { 1879596a2c1Sopenharmony_ci numberFormat = numberFormat.sign(signDisplay); 1889596a2c1Sopenharmony_ci } 1899596a2c1Sopenharmony_ci if (!notationString.empty()) { 1909596a2c1Sopenharmony_ci numberFormat = numberFormat.notation(notation); 1919596a2c1Sopenharmony_ci } 1929596a2c1Sopenharmony_ci InitDigitsProperties(); 1939596a2c1Sopenharmony_ci} 1949596a2c1Sopenharmony_ci 1959596a2c1Sopenharmony_civoid NumberFormat::InitDigitsProperties() 1969596a2c1Sopenharmony_ci{ 1979596a2c1Sopenharmony_ci int32_t status = 0; 1989596a2c1Sopenharmony_ci if (!maximumSignificantDigits.empty() || !minimumSignificantDigits.empty()) { 1999596a2c1Sopenharmony_ci int32_t maxSignificantDigits = ConvertString2Int(maximumSignificantDigits, status); 2009596a2c1Sopenharmony_ci if (status == 0) { 2019596a2c1Sopenharmony_ci numberFormat = numberFormat.precision(icu::number::Precision::maxSignificantDigits(maxSignificantDigits)); 2029596a2c1Sopenharmony_ci } 2039596a2c1Sopenharmony_ci 2049596a2c1Sopenharmony_ci status = 0; 2059596a2c1Sopenharmony_ci int32_t minSignificantDigits = ConvertString2Int(minimumSignificantDigits, status); 2069596a2c1Sopenharmony_ci if (status == 0) { 2079596a2c1Sopenharmony_ci numberFormat = numberFormat.precision(icu::number::Precision::minSignificantDigits(minSignificantDigits)); 2089596a2c1Sopenharmony_ci } 2099596a2c1Sopenharmony_ci } else { 2109596a2c1Sopenharmony_ci int32_t minIntegerDigits = ConvertString2Int(minimumIntegerDigits, status); 2119596a2c1Sopenharmony_ci if (status == 0 && minIntegerDigits > 1) { 2129596a2c1Sopenharmony_ci numberFormat = 2139596a2c1Sopenharmony_ci numberFormat.integerWidth(icu::number::IntegerWidth::zeroFillTo(minIntegerDigits)); 2149596a2c1Sopenharmony_ci } 2159596a2c1Sopenharmony_ci 2169596a2c1Sopenharmony_ci int32_t minFdStatus = 0; 2179596a2c1Sopenharmony_ci int32_t minFractionDigits = ConvertString2Int(minimumFractionDigits, minFdStatus); 2189596a2c1Sopenharmony_ci int32_t maxFdStatus = 0; 2199596a2c1Sopenharmony_ci int32_t maxFractionDigits = ConvertString2Int(maximumFractionDigits, maxFdStatus); 2209596a2c1Sopenharmony_ci if (minFdStatus == 0 || maxFdStatus == 0) { 2219596a2c1Sopenharmony_ci isSetFraction = true; 2229596a2c1Sopenharmony_ci } 2239596a2c1Sopenharmony_ci if (minFdStatus == 0 && maxFdStatus != 0) { 2249596a2c1Sopenharmony_ci numberFormat = 2259596a2c1Sopenharmony_ci numberFormat.precision(icu::number::Precision::minFraction(minFractionDigits)); 2269596a2c1Sopenharmony_ci } else if (minFdStatus != 0 && maxFdStatus == 0) { 2279596a2c1Sopenharmony_ci numberFormat = 2289596a2c1Sopenharmony_ci numberFormat.precision(icu::number::Precision::maxFraction(maxFractionDigits)); 2299596a2c1Sopenharmony_ci } else if (minFdStatus == 0 && maxFdStatus == 0) { 2309596a2c1Sopenharmony_ci numberFormat = 2319596a2c1Sopenharmony_ci numberFormat.precision(icu::number::Precision::minMaxFraction(minFractionDigits, maxFractionDigits)); 2329596a2c1Sopenharmony_ci } 2339596a2c1Sopenharmony_ci } 2349596a2c1Sopenharmony_ci} 2359596a2c1Sopenharmony_ci 2369596a2c1Sopenharmony_civoid NumberFormat::ParseConfigs(std::map<std::string, std::string> &configs) 2379596a2c1Sopenharmony_ci{ 2389596a2c1Sopenharmony_ci if (configs.count("signDisplay") > 0) { 2399596a2c1Sopenharmony_ci signDisplayString = configs["signDisplay"]; 2409596a2c1Sopenharmony_ci } 2419596a2c1Sopenharmony_ci if (signAutoStyle.count(signDisplayString) > 0) { 2429596a2c1Sopenharmony_ci signDisplay = signAutoStyle[signDisplayString]; 2439596a2c1Sopenharmony_ci } 2449596a2c1Sopenharmony_ci if (configs.count("style") > 0) { 2459596a2c1Sopenharmony_ci styleString = configs["style"]; 2469596a2c1Sopenharmony_ci } 2479596a2c1Sopenharmony_ci if (styleString == "unit" && configs.count("unit") > 0) { 2489596a2c1Sopenharmony_ci unit = configs["unit"]; 2499596a2c1Sopenharmony_ci if (configs.count("unitDisplay") > 0) { 2509596a2c1Sopenharmony_ci unitDisplayString = configs["unitDisplay"]; 2519596a2c1Sopenharmony_ci if (unitStyle.count(unitDisplayString) > 0) { 2529596a2c1Sopenharmony_ci unitDisplay = unitStyle[unitDisplayString]; 2539596a2c1Sopenharmony_ci } 2549596a2c1Sopenharmony_ci } 2559596a2c1Sopenharmony_ci if (configs.count("unitUsage") > 0) { 2569596a2c1Sopenharmony_ci unitUsage = configs["unitUsage"]; 2579596a2c1Sopenharmony_ci } 2589596a2c1Sopenharmony_ci } 2599596a2c1Sopenharmony_ci if (styleString == "currency" && configs.count("currency") > 0) { 2609596a2c1Sopenharmony_ci currency = GetCurrencyFromConfig(configs["currency"]); 2619596a2c1Sopenharmony_ci if (configs.count("currencySign") > 0) { 2629596a2c1Sopenharmony_ci currencySign = configs["currencySign"]; 2639596a2c1Sopenharmony_ci } 2649596a2c1Sopenharmony_ci if (currencySign.compare("accounting") == 0 && signAccountingStyle.count(signDisplayString) > 0) { 2659596a2c1Sopenharmony_ci signDisplay = signAccountingStyle[signDisplayString]; 2669596a2c1Sopenharmony_ci } 2679596a2c1Sopenharmony_ci if (configs.count("currencyDisplay") > 0 && currencyStyle.count(configs["currencyDisplay"]) > 0) { 2689596a2c1Sopenharmony_ci currencyDisplayString = configs["currencyDisplay"]; 2699596a2c1Sopenharmony_ci currencyDisplay = currencyStyle[currencyDisplayString]; 2709596a2c1Sopenharmony_ci } 2719596a2c1Sopenharmony_ci } 2729596a2c1Sopenharmony_ci ParseDigitsConfigs(configs); 2739596a2c1Sopenharmony_ci} 2749596a2c1Sopenharmony_ci 2759596a2c1Sopenharmony_civoid NumberFormat::ParseDigitsConfigs(std::map<std::string, std::string> &configs) 2769596a2c1Sopenharmony_ci{ 2779596a2c1Sopenharmony_ci if (configs.count("notation") > 0) { 2789596a2c1Sopenharmony_ci notationString = configs["notation"]; 2799596a2c1Sopenharmony_ci if (notationString == "scientific") { 2809596a2c1Sopenharmony_ci notation = icu::number::Notation::scientific(); 2819596a2c1Sopenharmony_ci } else if (notationString == "engineering") { 2829596a2c1Sopenharmony_ci notation = icu::number::Notation::engineering(); 2839596a2c1Sopenharmony_ci } 2849596a2c1Sopenharmony_ci if (notationString == "compact") { 2859596a2c1Sopenharmony_ci if (configs.count("compactDisplay") > 0) { 2869596a2c1Sopenharmony_ci compactDisplay = configs["compactDisplay"]; 2879596a2c1Sopenharmony_ci } 2889596a2c1Sopenharmony_ci if (compactDisplay == "long") { 2899596a2c1Sopenharmony_ci notation = icu::number::Notation::compactLong(); 2909596a2c1Sopenharmony_ci } else { 2919596a2c1Sopenharmony_ci notation = icu::number::Notation::compactShort(); 2929596a2c1Sopenharmony_ci } 2939596a2c1Sopenharmony_ci } 2949596a2c1Sopenharmony_ci } 2959596a2c1Sopenharmony_ci if (configs.count("minimumIntegerDigits") > 0) { 2969596a2c1Sopenharmony_ci minimumIntegerDigits = configs["minimumIntegerDigits"]; 2979596a2c1Sopenharmony_ci } 2989596a2c1Sopenharmony_ci if (configs.count("minimumFractionDigits") > 0) { 2999596a2c1Sopenharmony_ci minimumFractionDigits = configs["minimumFractionDigits"]; 3009596a2c1Sopenharmony_ci } 3019596a2c1Sopenharmony_ci if (configs.count("maximumFractionDigits") > 0) { 3029596a2c1Sopenharmony_ci maximumFractionDigits = configs["maximumFractionDigits"]; 3039596a2c1Sopenharmony_ci } 3049596a2c1Sopenharmony_ci if (configs.count("minimumSignificantDigits") > 0) { 3059596a2c1Sopenharmony_ci minimumSignificantDigits = configs["minimumSignificantDigits"]; 3069596a2c1Sopenharmony_ci } 3079596a2c1Sopenharmony_ci if (configs.count("maximumSignificantDigits") > 0) { 3089596a2c1Sopenharmony_ci maximumSignificantDigits = configs["maximumSignificantDigits"]; 3099596a2c1Sopenharmony_ci } 3109596a2c1Sopenharmony_ci if (configs.count("numberingSystem") > 0) { 3119596a2c1Sopenharmony_ci numberingSystem = configs["numberingSystem"]; 3129596a2c1Sopenharmony_ci } 3139596a2c1Sopenharmony_ci if (configs.count("useGrouping") > 0) { 3149596a2c1Sopenharmony_ci useGrouping = configs["useGrouping"]; 3159596a2c1Sopenharmony_ci } 3169596a2c1Sopenharmony_ci if (configs.count("localeMatcher") > 0) { 3179596a2c1Sopenharmony_ci localeMatcher = configs["localeMatcher"]; 3189596a2c1Sopenharmony_ci } 3199596a2c1Sopenharmony_ci} 3209596a2c1Sopenharmony_ci 3219596a2c1Sopenharmony_civoid NumberFormat::SetUnit(std::string &preferredUnit) 3229596a2c1Sopenharmony_ci{ 3239596a2c1Sopenharmony_ci if (preferredUnit.empty()) { 3249596a2c1Sopenharmony_ci return; 3259596a2c1Sopenharmony_ci } 3269596a2c1Sopenharmony_ci for (icu::MeasureUnit curUnit : unitArray) { 3279596a2c1Sopenharmony_ci if (!strcmp(curUnit.getSubtype(), preferredUnit.c_str())) { 3289596a2c1Sopenharmony_ci numberFormat = numberFormat.unit(curUnit); 3299596a2c1Sopenharmony_ci } 3309596a2c1Sopenharmony_ci } 3319596a2c1Sopenharmony_ci} 3329596a2c1Sopenharmony_ci 3339596a2c1Sopenharmony_cistd::string NumberFormat::Format(double number) 3349596a2c1Sopenharmony_ci{ 3359596a2c1Sopenharmony_ci if (!createSuccess) { 3369596a2c1Sopenharmony_ci return PseudoLocalizationProcessor(""); 3379596a2c1Sopenharmony_ci } 3389596a2c1Sopenharmony_ci double finalNumber = number; 3399596a2c1Sopenharmony_ci std::string finalUnit = unit; 3409596a2c1Sopenharmony_ci if ((unitUsage == "size-file-byte" || unitUsage == "size-shortfile-byte") && ConvertByte(finalNumber, finalUnit)) { 3419596a2c1Sopenharmony_ci SetUnit(finalUnit); 3429596a2c1Sopenharmony_ci SetPrecisionWithByte(finalNumber, finalUnit); 3439596a2c1Sopenharmony_ci } else if (unitUsage == "elapsed-time-second" && ConvertDate(finalNumber, finalUnit) && 3449596a2c1Sopenharmony_ci relativeTimeFormat != nullptr) { 3459596a2c1Sopenharmony_ci return relativeTimeFormat->Format(finalNumber, finalUnit); 3469596a2c1Sopenharmony_ci } else if (!unitUsage.empty()) { 3479596a2c1Sopenharmony_ci std::vector<std::string> preferredUnits; 3489596a2c1Sopenharmony_ci if (unitUsage == "default") { 3499596a2c1Sopenharmony_ci GetDefaultPreferredUnit(localeInfo->GetRegion(), unitType, preferredUnits); 3509596a2c1Sopenharmony_ci } else { 3519596a2c1Sopenharmony_ci GetPreferredUnit(localeInfo->GetRegion(), unitUsage, preferredUnits); 3529596a2c1Sopenharmony_ci } 3539596a2c1Sopenharmony_ci std::map<double, std::string> preferredValuesOverOne; 3549596a2c1Sopenharmony_ci std::map<double, std::string> preferredValuesUnderOne; 3559596a2c1Sopenharmony_ci double num = number; 3569596a2c1Sopenharmony_ci for (size_t i = 0; i < preferredUnits.size(); i++) { 3579596a2c1Sopenharmony_ci int status = Convert(num, unit, unitMeasSys, preferredUnits[i], unitMeasSys); 3589596a2c1Sopenharmony_ci if (!status) { 3599596a2c1Sopenharmony_ci continue; 3609596a2c1Sopenharmony_ci } 3619596a2c1Sopenharmony_ci if (num >= 1) { 3629596a2c1Sopenharmony_ci preferredValuesOverOne.insert(std::make_pair(num, preferredUnits[i])); 3639596a2c1Sopenharmony_ci } else { 3649596a2c1Sopenharmony_ci preferredValuesUnderOne.insert(std::make_pair(num, preferredUnits[i])); 3659596a2c1Sopenharmony_ci } 3669596a2c1Sopenharmony_ci } 3679596a2c1Sopenharmony_ci std::string preferredUnit; 3689596a2c1Sopenharmony_ci if (preferredValuesOverOne.size() > 0) { 3699596a2c1Sopenharmony_ci finalNumber = preferredValuesOverOne.begin()->first; 3709596a2c1Sopenharmony_ci preferredUnit = preferredValuesOverOne.begin()->second; 3719596a2c1Sopenharmony_ci } else if (preferredValuesUnderOne.size() > 0) { 3729596a2c1Sopenharmony_ci finalNumber = preferredValuesUnderOne.rbegin()->first; 3739596a2c1Sopenharmony_ci preferredUnit = preferredValuesUnderOne.rbegin()->second; 3749596a2c1Sopenharmony_ci } 3759596a2c1Sopenharmony_ci SetUnit(preferredUnit); 3769596a2c1Sopenharmony_ci } 3779596a2c1Sopenharmony_ci std::string result; 3789596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 3799596a2c1Sopenharmony_ci numberFormat.formatDouble(finalNumber, status).toString(status).toUTF8String(result); 3809596a2c1Sopenharmony_ci return PseudoLocalizationProcessor(result); 3819596a2c1Sopenharmony_ci} 3829596a2c1Sopenharmony_ci 3839596a2c1Sopenharmony_civoid NumberFormat::GetResolvedOptions(std::map<std::string, std::string> &map) 3849596a2c1Sopenharmony_ci{ 3859596a2c1Sopenharmony_ci map.insert(std::make_pair("locale", localeBaseName)); 3869596a2c1Sopenharmony_ci if (!styleString.empty()) { 3879596a2c1Sopenharmony_ci map.insert(std::make_pair("style", styleString)); 3889596a2c1Sopenharmony_ci } 3899596a2c1Sopenharmony_ci if (!currency.empty()) { 3909596a2c1Sopenharmony_ci map.insert(std::make_pair("currency", currency)); 3919596a2c1Sopenharmony_ci } 3929596a2c1Sopenharmony_ci if (!currencySign.empty()) { 3939596a2c1Sopenharmony_ci map.insert(std::make_pair("currencySign", currencySign)); 3949596a2c1Sopenharmony_ci } 3959596a2c1Sopenharmony_ci if (!currencyDisplayString.empty()) { 3969596a2c1Sopenharmony_ci map.insert(std::make_pair("currencyDisplay", currencyDisplayString)); 3979596a2c1Sopenharmony_ci } 3989596a2c1Sopenharmony_ci if (!signDisplayString.empty()) { 3999596a2c1Sopenharmony_ci map.insert(std::make_pair("signDisplay", signDisplayString)); 4009596a2c1Sopenharmony_ci } 4019596a2c1Sopenharmony_ci if (!compactDisplay.empty()) { 4029596a2c1Sopenharmony_ci map.insert(std::make_pair("compactDisplay", compactDisplay)); 4039596a2c1Sopenharmony_ci } 4049596a2c1Sopenharmony_ci if (!unitDisplayString.empty()) { 4059596a2c1Sopenharmony_ci map.insert(std::make_pair("unitDisplay", unitDisplayString)); 4069596a2c1Sopenharmony_ci } 4079596a2c1Sopenharmony_ci if (!unitUsage.empty()) { 4089596a2c1Sopenharmony_ci map.insert(std::make_pair("unitUsage", unitUsage)); 4099596a2c1Sopenharmony_ci } 4109596a2c1Sopenharmony_ci if (!unit.empty()) { 4119596a2c1Sopenharmony_ci map.insert(std::make_pair("unit", unit)); 4129596a2c1Sopenharmony_ci } 4139596a2c1Sopenharmony_ci GetDigitsResolvedOptions(map); 4149596a2c1Sopenharmony_ci} 4159596a2c1Sopenharmony_ci 4169596a2c1Sopenharmony_civoid NumberFormat::GetDigitsResolvedOptions(std::map<std::string, std::string> &map) 4179596a2c1Sopenharmony_ci{ 4189596a2c1Sopenharmony_ci if (!numberingSystem.empty()) { 4199596a2c1Sopenharmony_ci map.insert(std::make_pair("numberingSystem", numberingSystem)); 4209596a2c1Sopenharmony_ci } else if (!(localeInfo->GetNumberingSystem()).empty()) { 4219596a2c1Sopenharmony_ci map.insert(std::make_pair("numberingSystem", localeInfo->GetNumberingSystem())); 4229596a2c1Sopenharmony_ci } else { 4239596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 4249596a2c1Sopenharmony_ci auto numSys = std::unique_ptr<icu::NumberingSystem>(icu::NumberingSystem::createInstance(locale, status)); 4259596a2c1Sopenharmony_ci if (U_SUCCESS(status)) { 4269596a2c1Sopenharmony_ci map.insert(std::make_pair("numberingSystem", numSys->getName())); 4279596a2c1Sopenharmony_ci } 4289596a2c1Sopenharmony_ci } 4299596a2c1Sopenharmony_ci if (!useGrouping.empty()) { 4309596a2c1Sopenharmony_ci map.insert(std::make_pair("useGrouping", useGrouping)); 4319596a2c1Sopenharmony_ci } 4329596a2c1Sopenharmony_ci if (!minimumIntegerDigits.empty()) { 4339596a2c1Sopenharmony_ci map.insert(std::make_pair("minimumIntegerDigits", minimumIntegerDigits)); 4349596a2c1Sopenharmony_ci } 4359596a2c1Sopenharmony_ci if (!minimumFractionDigits.empty()) { 4369596a2c1Sopenharmony_ci map.insert(std::make_pair("minimumFractionDigits", minimumFractionDigits)); 4379596a2c1Sopenharmony_ci } 4389596a2c1Sopenharmony_ci if (!maximumFractionDigits.empty()) { 4399596a2c1Sopenharmony_ci map.insert(std::make_pair("maximumFractionDigits", maximumFractionDigits)); 4409596a2c1Sopenharmony_ci } 4419596a2c1Sopenharmony_ci if (!minimumSignificantDigits.empty()) { 4429596a2c1Sopenharmony_ci map.insert(std::make_pair("minimumSignificantDigits", minimumSignificantDigits)); 4439596a2c1Sopenharmony_ci } 4449596a2c1Sopenharmony_ci if (!maximumSignificantDigits.empty()) { 4459596a2c1Sopenharmony_ci map.insert(std::make_pair("maximumSignificantDigits", maximumSignificantDigits)); 4469596a2c1Sopenharmony_ci } 4479596a2c1Sopenharmony_ci if (!localeMatcher.empty()) { 4489596a2c1Sopenharmony_ci map.insert(std::make_pair("localeMatcher", localeMatcher)); 4499596a2c1Sopenharmony_ci } 4509596a2c1Sopenharmony_ci if (!notationString.empty()) { 4519596a2c1Sopenharmony_ci map.insert(std::make_pair("notation", notationString)); 4529596a2c1Sopenharmony_ci } 4539596a2c1Sopenharmony_ci} 4549596a2c1Sopenharmony_ci 4559596a2c1Sopenharmony_civoid NumberFormat::SetPrecisionWithByte(double number, const std::string& finalUnit) 4569596a2c1Sopenharmony_ci{ 4579596a2c1Sopenharmony_ci if (isSetFraction) { 4589596a2c1Sopenharmony_ci return; 4599596a2c1Sopenharmony_ci } 4609596a2c1Sopenharmony_ci int32_t FractionDigits = -1; 4619596a2c1Sopenharmony_ci // 100 is the threshold between different decimal 4629596a2c1Sopenharmony_ci if (finalUnit == "byte" || number >= 100) { 4639596a2c1Sopenharmony_ci FractionDigits = 0; 4649596a2c1Sopenharmony_ci } else if (number < 1) { 4659596a2c1Sopenharmony_ci // 2 is the number of significant digits in the decimal 4669596a2c1Sopenharmony_ci FractionDigits = 2; 4679596a2c1Sopenharmony_ci // 10 is the threshold between different decimal 4689596a2c1Sopenharmony_ci } else if (number < 10) { 4699596a2c1Sopenharmony_ci if (unitUsage == "size-shortfile-byte") { 4709596a2c1Sopenharmony_ci FractionDigits = 1; 4719596a2c1Sopenharmony_ci } else { 4729596a2c1Sopenharmony_ci // 2 is the number of significant digits in the decimal 4739596a2c1Sopenharmony_ci FractionDigits = 2; 4749596a2c1Sopenharmony_ci } 4759596a2c1Sopenharmony_ci } else { 4769596a2c1Sopenharmony_ci if (unitUsage == "size-shortfile-byte") { 4779596a2c1Sopenharmony_ci FractionDigits = 0; 4789596a2c1Sopenharmony_ci } else { 4799596a2c1Sopenharmony_ci // 2 is the number of significant digits in the decimal 4809596a2c1Sopenharmony_ci FractionDigits = 2; 4819596a2c1Sopenharmony_ci } 4829596a2c1Sopenharmony_ci } 4839596a2c1Sopenharmony_ci if (FractionDigits != -1) { 4849596a2c1Sopenharmony_ci numberFormat = numberFormat.precision(icu::number::Precision::minMaxFraction(FractionDigits, FractionDigits)); 4859596a2c1Sopenharmony_ci } 4869596a2c1Sopenharmony_ci} 4879596a2c1Sopenharmony_ci 4889596a2c1Sopenharmony_cistd::string NumberFormat::GetCurrency() const 4899596a2c1Sopenharmony_ci{ 4909596a2c1Sopenharmony_ci return currency; 4919596a2c1Sopenharmony_ci} 4929596a2c1Sopenharmony_ci 4939596a2c1Sopenharmony_cistd::string NumberFormat::GetCurrencySign() const 4949596a2c1Sopenharmony_ci{ 4959596a2c1Sopenharmony_ci return currencySign; 4969596a2c1Sopenharmony_ci} 4979596a2c1Sopenharmony_ci 4989596a2c1Sopenharmony_cistd::string NumberFormat::GetStyle() const 4999596a2c1Sopenharmony_ci{ 5009596a2c1Sopenharmony_ci return styleString; 5019596a2c1Sopenharmony_ci} 5029596a2c1Sopenharmony_ci 5039596a2c1Sopenharmony_cistd::string NumberFormat::GetNumberingSystem() const 5049596a2c1Sopenharmony_ci{ 5059596a2c1Sopenharmony_ci return numberingSystem; 5069596a2c1Sopenharmony_ci} 5079596a2c1Sopenharmony_ci 5089596a2c1Sopenharmony_cistd::string NumberFormat::GetUseGrouping() const 5099596a2c1Sopenharmony_ci{ 5109596a2c1Sopenharmony_ci return useGrouping; 5119596a2c1Sopenharmony_ci} 5129596a2c1Sopenharmony_ci 5139596a2c1Sopenharmony_cistd::string NumberFormat::GetMinimumIntegerDigits() const 5149596a2c1Sopenharmony_ci{ 5159596a2c1Sopenharmony_ci return minimumIntegerDigits; 5169596a2c1Sopenharmony_ci} 5179596a2c1Sopenharmony_ci 5189596a2c1Sopenharmony_cistd::string NumberFormat::GetMinimumFractionDigits() const 5199596a2c1Sopenharmony_ci{ 5209596a2c1Sopenharmony_ci return minimumFractionDigits; 5219596a2c1Sopenharmony_ci} 5229596a2c1Sopenharmony_ci 5239596a2c1Sopenharmony_cistd::string NumberFormat::GetMaximumFractionDigits() const 5249596a2c1Sopenharmony_ci{ 5259596a2c1Sopenharmony_ci return maximumFractionDigits; 5269596a2c1Sopenharmony_ci} 5279596a2c1Sopenharmony_ci 5289596a2c1Sopenharmony_cistd::string NumberFormat::GetMinimumSignificantDigits() const 5299596a2c1Sopenharmony_ci{ 5309596a2c1Sopenharmony_ci return minimumSignificantDigits; 5319596a2c1Sopenharmony_ci} 5329596a2c1Sopenharmony_ci 5339596a2c1Sopenharmony_cistd::string NumberFormat::GetMaximumSignificantDigits() const 5349596a2c1Sopenharmony_ci{ 5359596a2c1Sopenharmony_ci return maximumSignificantDigits; 5369596a2c1Sopenharmony_ci} 5379596a2c1Sopenharmony_ci 5389596a2c1Sopenharmony_cistd::string NumberFormat::GetLocaleMatcher() const 5399596a2c1Sopenharmony_ci{ 5409596a2c1Sopenharmony_ci return localeMatcher; 5419596a2c1Sopenharmony_ci} 5429596a2c1Sopenharmony_ci 5439596a2c1Sopenharmony_cibool NumberFormat::Init() 5449596a2c1Sopenharmony_ci{ 5459596a2c1Sopenharmony_ci SetHwIcuDirectory(); 5469596a2c1Sopenharmony_ci return true; 5479596a2c1Sopenharmony_ci} 5489596a2c1Sopenharmony_ci 5499596a2c1Sopenharmony_civoid NumberFormat::SetDefaultStyle() 5509596a2c1Sopenharmony_ci{ 5519596a2c1Sopenharmony_ci char value[BUFFER_LEN]; 5529596a2c1Sopenharmony_ci int code = GetParameter(DEVICE_TYPE_NAME, "", value, BUFFER_LEN); 5539596a2c1Sopenharmony_ci if (code > 0) { 5549596a2c1Sopenharmony_ci std::string deviceType = value; 5559596a2c1Sopenharmony_ci if (defaultUnitStyle.find(deviceType) != defaultUnitStyle.end()) { 5569596a2c1Sopenharmony_ci unitDisplay = defaultUnitStyle[deviceType]; 5579596a2c1Sopenharmony_ci } 5589596a2c1Sopenharmony_ci if (defaultCurrencyStyle.find(deviceType) != defaultCurrencyStyle.end()) { 5599596a2c1Sopenharmony_ci currencyDisplay = defaultCurrencyStyle[deviceType]; 5609596a2c1Sopenharmony_ci } 5619596a2c1Sopenharmony_ci } 5629596a2c1Sopenharmony_ci} 5639596a2c1Sopenharmony_ci 5649596a2c1Sopenharmony_cibool NumberFormat::ReadISO4217Ddatas() 5659596a2c1Sopenharmony_ci{ 5669596a2c1Sopenharmony_ci if (numToCurrency.size()) { 5679596a2c1Sopenharmony_ci return true; 5689596a2c1Sopenharmony_ci } 5699596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 5709596a2c1Sopenharmony_ci const char *currentCurrency; 5719596a2c1Sopenharmony_ci UEnumeration *currencies = ucurr_openISOCurrencies(UCURR_ALL, &status); 5729596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 5739596a2c1Sopenharmony_ci return false; 5749596a2c1Sopenharmony_ci } 5759596a2c1Sopenharmony_ci 5769596a2c1Sopenharmony_ci UChar code[CURRENCY_LEN + 1]; // +1 includes the NUL 5779596a2c1Sopenharmony_ci int32_t length = 0; 5789596a2c1Sopenharmony_ci while ((currentCurrency = uenum_next(currencies, &length, &status)) != NULL) { 5799596a2c1Sopenharmony_ci u_charsToUChars(currentCurrency, code, length + 1); // +1 includes the NUL 5809596a2c1Sopenharmony_ci const UChar* currencyCode = code; 5819596a2c1Sopenharmony_ci int32_t numCode = ucurr_getNumericCode(currencyCode); 5829596a2c1Sopenharmony_ci if (numCode == 0) { 5839596a2c1Sopenharmony_ci continue; 5849596a2c1Sopenharmony_ci } 5859596a2c1Sopenharmony_ci std::stringstream ss; 5869596a2c1Sopenharmony_ci ss << std::setw(CURRENCY_LEN) << std::setfill('0') << numCode; // fill with '0' 5879596a2c1Sopenharmony_ci numToCurrency.insert(std::make_pair<std::string, std::string>(ss.str(), currentCurrency)); 5889596a2c1Sopenharmony_ci } 5899596a2c1Sopenharmony_ci uenum_close(currencies); 5909596a2c1Sopenharmony_ci return !numToCurrency.empty(); 5919596a2c1Sopenharmony_ci} 5929596a2c1Sopenharmony_ci 5939596a2c1Sopenharmony_cistd::string NumberFormat::GetCurrencyFromConfig(const std::string& currency) 5949596a2c1Sopenharmony_ci{ 5959596a2c1Sopenharmony_ci if (currency.size() != CURRENCY_LEN) { 5969596a2c1Sopenharmony_ci HILOG_ERROR_I18N("Invalid currency code : %{public}s", currency.c_str()); 5979596a2c1Sopenharmony_ci return ""; 5989596a2c1Sopenharmony_ci } 5999596a2c1Sopenharmony_ci bool isAlpha = true; 6009596a2c1Sopenharmony_ci for (auto c : currency) { 6019596a2c1Sopenharmony_ci isAlpha = std::isalpha(c); 6029596a2c1Sopenharmony_ci if (!isAlpha) { 6039596a2c1Sopenharmony_ci break; 6049596a2c1Sopenharmony_ci } 6059596a2c1Sopenharmony_ci } 6069596a2c1Sopenharmony_ci if (isAlpha) { 6079596a2c1Sopenharmony_ci return currency; 6089596a2c1Sopenharmony_ci } 6099596a2c1Sopenharmony_ci if (ReadISO4217Ddatas() && numToCurrency.find(currency) != numToCurrency.end()) { 6109596a2c1Sopenharmony_ci return numToCurrency[currency]; 6119596a2c1Sopenharmony_ci } 6129596a2c1Sopenharmony_ci HILOG_ERROR_I18N("Invalid currency code : %{public}s", currency.c_str()); 6139596a2c1Sopenharmony_ci return ""; 6149596a2c1Sopenharmony_ci} 6159596a2c1Sopenharmony_ci} // namespace I18n 6169596a2c1Sopenharmony_ci} // namespace Global 6179596a2c1Sopenharmony_ci} // namespace OHOS 618