update intl

Signed-off-by: meaty-bag-and-wangwang-meat <zouzhexi@huawei.com>
This commit is contained in:
meaty-bag-and-wangwang-meat 2021-07-19 13:02:47 +08:00
parent 9e58807aec
commit f7b21f5fce
11 changed files with 874 additions and 212 deletions

View File

@ -22,7 +22,10 @@ config("intl_config") {
]
}
ohos_shared_library("intl_util") {
configs = [ ":intl_config" ]
configs = [
":intl_config",
"//build/config/compiler:rtti"
]
include_dirs = [
"//third_party/icu/icu4c/source",
"//third_party/icu/icu4c/source/common",
@ -37,6 +40,7 @@ ohos_shared_library("intl_util") {
cflags_cc = [
"-Wall",
"-fPIC",
"-frtti",
]
deps = [
"//third_party/icu/icu4c:shared_icui18n",

View File

@ -24,6 +24,7 @@
#include "unicode/timezone.h"
#include "unicode/calendar.h"
#include "unicode/numsys.h"
#include "unicode/dtitvfmt.h"
#include <map>
#include <vector>
#include <climits>
@ -37,7 +38,8 @@ public:
DateTimeFormat(std::string locale);
DateTimeFormat(const std::vector<std::string> &localeTags, std::map<std::string, std::string> &configs);
virtual ~DateTimeFormat();
std::string Format(int year, int month, int day, int hour, int minute, int second);
std::string Format(int64_t *date);
std::string FormatRange(int64_t *fromDate, int64_t *toDate);
void GetResolvedOptions(std::map<std::string, std::string> &map);
std::string GetDateStyle() const;
std::string GetTimeStyle() const;
@ -54,10 +56,12 @@ public:
std::string GetHour() const;
std::string GetMinute() const;
std::string GetSecond() const;
std::string GetDayPeriod() const;
std::string GetLocaleMatcher() const;
std::string GetFormatMatcher() const;
std::string GetFractionalSecondDigits() const;
private:
static std::map<std::string, icu::DateFormat::EStyle> dateTimeStyle;
std::set<std::string> allValidLocales;
std::string localeTag;
std::string dateStyle;
std::string timeStyle;
@ -73,9 +77,12 @@ private:
std::string hour;
std::string minute;
std::string second;
std::string fractionalSecondDigits;
std::string timeZoneName;
std::string dayPeriod;
std::string localeMatcher;
std::string formatMatcher;
icu::DateFormat *dateFormat;
icu::DateIntervalFormat *dateIntvFormat;
icu::Calendar *calendar;
LocaleInfo *localeInfo;
icu::Locale locale;
@ -98,12 +105,20 @@ private:
static const int32_t SHORT_LENGTH = 3;
static const int32_t LONG_LENGTH = 4;
static const int32_t NARROW_LENGTH = 5;
static const int32_t YEAR_INDEX = 0;
static const int32_t MONTH_INDEX = 1;
static const int32_t DAY_INDEX = 2;
static const int32_t HOUR_INDEX = 3;
static const int32_t MINUTE_INDEX = 4;
static const int32_t SECOND_INDEX = 5;
static const int32_t SHORT_ERA_LENGTH = 1;
static const int32_t LONG_ERA_LENGTH = 4;
static const int HALF_HOUR = 30;
static const int HOURS_OF_A_DAY = 24;
static bool icuInitialized;
static bool Init();
static std::set<std::string> allValidLocales;
static std::set<std::string> GetValidLocales();
void ParseConfigsPartOne(std::map<std::string, std::string> &configs);
void ParseConfigsPartTwo(std::map<std::string, std::string> &configs);
void AddOptions(std::string option, char16_t optionChar);
@ -114,7 +129,6 @@ private:
void ComputeHourCycleChars();
void ComputeWeekdayOrEraOfPattern(std::string option, char16_t character, std::string longChar,
std::string shortChar, std::string narrowChar);
void GetValidLocales();
void InitDateFormat(UErrorCode &status);
void GetAdditionalResolvedOptions(std::map<std::string, std::string> &map);
};

View File

@ -15,11 +15,18 @@
#ifndef OHOS_GLOBAL_I18N_NUMBER_FORMAT_H
#define OHOS_GLOBAL_I18N_NUMBER_FORMAT_H
#include "unicode/numberformatter.h"
#include "unicode/locid.h"
#include "unicode/numfmt.h"
#include "unicode/unum.h"
#include "unicode/decimfmt.h"
#include "unicode/localebuilder.h"
#include "unicode/numsys.h"
#include "unicode/measfmt.h"
#include "unicode/measunit.h"
#include "unicode/measure.h"
#include "unicode/currunit.h"
#include "unicode/fmtable.h"
#include "number_utils.h"
#include "number_utypes.h"
#include "locale_info.h"
@ -36,34 +43,57 @@ public:
virtual ~NumberFormat();
std::string Format(double number);
void GetResolvedOptions(std::map<std::string, std::string> &map);
std::string GetCurrency();
std::string GetCurrencySign();
std::string GetStyle();
std::string GetNumberingSystem();
std::string GetUseGrouping();
std::string GetMinimumIntegerDigits();
std::string GetMinimumFractionDigits();
std::string GetMaximumFractionDigits();
std::string GetCurrency() const;
std::string GetCurrencySign() const;
std::string GetStyle() const;
std::string GetNumberingSystem() const;
std::string GetUseGrouping() const;
std::string GetMinimumIntegerDigits() const;
std::string GetMinimumFractionDigits() const;
std::string GetMaximumFractionDigits() const;
std::string GetMinimumSignificantDigits() const;
std::string GetMaximumSignificantDigits() const;
std::string GetLocaleMatcher() const;
private:
icu::Locale locale;
std::string currency;
std::string currencySign;
std::string currencyDisplayString;
std::string unit;
std::string unitDisplayString;
std::string styleString;
std::string numberingSystem;
std::string useGrouping;
std::string notationString;
std::string signDisplayString;
std::string compactDisplay;
std::string minimumIntegerDigits;
std::string minimumFractionDigits;
std::string maximumFractionDigits;
std::string minimumSignificantDigits;
std::string maximumSignificantDigits;
std::string localeBaseName;
std::string localeMatcher;
LocaleInfo *localeInfo;
icu::NumberFormat *numberFormat;
UNumberFormatStyle style = UNumberFormatStyle::UNUM_DECIMAL;
static std::map<std::string, UNumberFormatStyle> formatStyle;
std::set<std::string> allValidLocales;
icu::number::LocalizedNumberFormatter numberFormat;
icu::number::Notation notation = icu::number::Notation::simple();
UNumberUnitWidth unitDisplay = UNumberUnitWidth::UNUM_UNIT_WIDTH_SHORT;
UNumberUnitWidth currencyDisplay = UNumberUnitWidth::UNUM_UNIT_WIDTH_SHORT;
UNumberSignDisplay signDisplay = UNumberSignDisplay::UNUM_SIGN_AUTO;
static const int MAX_UNIT_NUM = 500;
icu::MeasureUnit unitArray[MAX_UNIT_NUM];
static std::map<std::string, UNumberUnitWidth> unitStyle;
static std::map<std::string, UNumberUnitWidth> currencyStyle;
static std::map<std::string, UNumberSignDisplay> signAutoStyle;
static std::map<std::string, UNumberSignDisplay> signAccountingStyle;
static std::set<std::string> allValidLocales;
static std::set<std::string> GetValidLocales();
void ParseConfigs(std::map<std::string, std::string> &configs);
void GetValidLocales();
void ParseDigitsConfigs(std::map<std::string, std::string> &configs);
void GetDigitsResolvedOptions(std::map<std::string, std::string> &map);
void InitProperties();
void InitDigitsProperties();
static bool icuInitialized;
static bool Init();
};

View File

@ -16,6 +16,7 @@
#include "ohos/init_data.h"
#include <algorithm>
#include <cmath>
#include <iostream>
namespace OHOS {
namespace Global {
@ -47,13 +48,17 @@ DateTimeFormat::DateTimeFormat(std::string localeTag)
dateFormat->setCalendar(*calendar);
}
void DateTimeFormat::GetValidLocales()
std::set<std::string> DateTimeFormat::allValidLocales = GetValidLocales();
std::set<std::string> DateTimeFormat::GetValidLocales()
{
int32_t validCount = 1;
const Locale *validLocales = Locale::getAvailableLocales(validCount);
std::set<std::string> allValidLocales;
for (int i = 0; i < validCount; i++) {
allValidLocales.insert(validLocales[i].getLanguage());
}
return allValidLocales;
}
DateTimeFormat::DateTimeFormat(const std::vector<std::string> &localeTags, std::map<std::string, std::string> &configs)
@ -75,7 +80,11 @@ DateTimeFormat::DateTimeFormat(const std::vector<std::string> &localeTags, std::
}
ComputeHourCycleChars();
ComputeSkeleton();
InitDateFormat(status);
if (configs.size() == 0) {
dateFormat = DateFormat::createDateInstance(DateFormat::SHORT, locale);
} else {
InitDateFormat(status);
}
if (dateFormat == nullptr) {
continue;
}
@ -88,6 +97,9 @@ DateTimeFormat::DateTimeFormat(const std::vector<std::string> &localeTags, std::
std::replace(localeTag.begin(), localeTag.end(), '_', '-');
dateFormat = DateFormat::createInstance();
}
if (dateIntvFormat == nullptr) {
dateIntvFormat = DateIntervalFormat::createInstance(pattern, status);
}
calendar = Calendar::createInstance(locale, status);
}
@ -109,20 +121,28 @@ DateTimeFormat::~DateTimeFormat()
void DateTimeFormat::InitDateFormat(UErrorCode &status)
{
if (!dateStyle.empty() && timeStyle.empty()) {
dateFormat = DateFormat::createDateInstance(dateTimeStyle[dateStyle], locale);
} else if (dateStyle.empty() && !timeStyle.empty()) {
dateFormat = DateFormat::createTimeInstance(dateTimeStyle[timeStyle], locale);
} else if (!dateStyle.empty() && !timeStyle.empty()) {
dateFormat = DateFormat::createDateTimeInstance(dateTimeStyle[dateStyle], dateTimeStyle[timeStyle], locale);
if (!dateStyle.empty() || !timeStyle.empty()) {
DateFormat::EStyle dateStyleValue = DateFormat::EStyle::kNone;
DateFormat::EStyle timeStyleValue = DateFormat::EStyle::kNone;
if (!dateStyle.empty()) {
dateStyleValue = dateTimeStyle[dateStyle];
}
if (!timeStyle.empty()) {
timeStyleValue = dateTimeStyle[timeStyle];
}
dateFormat = DateFormat::createDateTimeInstance(dateStyleValue, timeStyleValue, locale);
auto simpleDateFormat = std::unique_ptr<SimpleDateFormat>(dynamic_cast<SimpleDateFormat*>(dateFormat));
simpleDateFormat->toPattern(pattern);
} else {
auto patternGenerator =
std::unique_ptr<DateTimePatternGenerator>(DateTimePatternGenerator::createInstance(locale, status));
ComputePattern();
pattern = patternGenerator->replaceFieldTypes(patternGenerator->getBestPattern(pattern, status), pattern, status);
pattern =
patternGenerator->replaceFieldTypes(patternGenerator->getBestPattern(pattern, status), pattern, status);
pattern = patternGenerator->getBestPattern(pattern, status);
dateFormat = new SimpleDateFormat(pattern, locale, status);
}
dateIntvFormat = DateIntervalFormat::createInstance(pattern, locale, status);
}
void DateTimeFormat::ParseConfigsPartOne(std::map<std::string, std::string> &configs)
@ -133,28 +153,6 @@ void DateTimeFormat::ParseConfigsPartOne(std::map<std::string, std::string> &con
if (configs.count("timeStyle") > 0) {
timeStyle = configs["timeStyle"];
}
if (configs.count("hourCycle") > 0) {
hourCycle = configs["hourCycle"];
}
if (configs.count("timeZone") > 0) {
timeZone = configs["timeZone"];
}
if (configs.count("numberingSystem") > 0) {
numberingSystem = configs["numberingSystem"];
}
if (configs.count("hour12") > 0) {
hour12 = configs["hour12"];
}
if (configs.count("weekday") > 0) {
weekday = configs["weekday"];
}
if (configs.count("era") > 0) {
era = configs["era"];
}
}
void DateTimeFormat::ParseConfigsPartTwo(std::map<std::string, std::string> &configs)
{
if (configs.count("year") > 0) {
year = configs["year"];
}
@ -173,26 +171,56 @@ void DateTimeFormat::ParseConfigsPartTwo(std::map<std::string, std::string> &con
if (configs.count("second") > 0) {
second = configs["second"];
}
if (configs.count("fractionalSecondDigits") > 0) {
fractionalSecondDigits = configs["fractionalSecondDigits"];
}
void DateTimeFormat::ParseConfigsPartTwo(std::map<std::string, std::string> &configs)
{
if (configs.count("hourCycle") > 0) {
hourCycle = configs["hourCycle"];
}
if (configs.count("timeZone") > 0) {
timeZone = configs["timeZone"];
}
if (configs.count("numberingSystem") > 0) {
numberingSystem = configs["numberingSystem"];
}
if (configs.count("hour12") > 0) {
hour12 = configs["hour12"];
}
if (configs.count("weekday") > 0) {
weekday = configs["weekday"];
}
if (configs.count("era") > 0) {
era = configs["era"];
}
if (configs.count("timeZoneName") > 0) {
timeZoneName = configs["timeZoneName"];
}
if (configs.count("dayPeriod") > 0) {
dayPeriod = configs["dayPeriod"];
}
if (configs.count("localeMatcher") > 0) {
localeMatcher = configs["localeMatcher"];
}
if (configs.count("formatMatcher") > 0) {
formatMatcher = configs["formatMatcher"];
}
}
void DateTimeFormat::ComputeSkeleton()
{
if (year.empty() && month.empty() && day.empty() && hour.empty() && minute.empty() && second.empty()) {
pattern.append("yMd");
}
AddOptions(year, yearChar);
AddOptions(month, monthChar);
AddOptions(day, dayChar);
AddOptions(hour, hourChar);
AddOptions(minute, minuteChar);
AddOptions(second, secondChar);
if (hourCycle == "h12" || hourCycle == "h11" || hour12 == "true") {
if ((hourCycle == "h12" || hourCycle == "h11" || hour12 == "true") && !hour.empty()) {
pattern.append(amPmChar);
}
AddOptions(fractionalSecondDigits, fractionalSecondChar);
AddOptions(timeZoneName, timeZoneChar);
AddOptions(weekday, weekdayChar);
AddOptions(era, eraChar);
@ -299,11 +327,17 @@ void DateTimeFormat::ComputeWeekdayOrEraOfPattern(std::string option, char16_t c
bool DateTimeFormat::icuInitialized = DateTimeFormat::Init();
std::string DateTimeFormat::Format(int year, int month, int day, int hour, int minute, int second)
std::string DateTimeFormat::Format(int64_t *date)
{
UErrorCode status = U_ZERO_ERROR;
std::string result;
UnicodeString dateString;
int64_t year = date[YEAR_INDEX];
int64_t month = date[MONTH_INDEX];
int64_t day = date[DAY_INDEX];
int64_t hour = date[HOUR_INDEX];
int64_t minute = date[MINUTE_INDEX];
int64_t second = date[SECOND_INDEX];
calendar->clear();
calendar->set(year, month, day, hour, minute, second);
@ -319,6 +353,50 @@ std::string DateTimeFormat::Format(int year, int month, int day, int hour, int m
return result;
}
std::string DateTimeFormat::FormatRange(int64_t *fromDate, int64_t *toDate)
{
UErrorCode status = U_ZERO_ERROR;
std::string result;
UnicodeString dateString;
int64_t year = fromDate[YEAR_INDEX];
int64_t month = fromDate[MONTH_INDEX];
int64_t day = fromDate[DAY_INDEX];
int64_t hour = fromDate[HOUR_INDEX];
int64_t minute = fromDate[MINUTE_INDEX];
int64_t second = fromDate[SECOND_INDEX];
calendar->clear();
calendar->set(year, month, day, hour, minute, second);
if (!timeZone.empty()) {
UDate timestamp = calendar->getTime(status);
auto zone = std::unique_ptr<TimeZone>(TimeZone::createTimeZone(timeZone.c_str()));
calendar->setTimeZone(*zone);
dateIntvFormat->setTimeZone(*zone);
calendar->setTime(timestamp, status);
}
year = toDate[YEAR_INDEX];
month = toDate[MONTH_INDEX];
day = toDate[DAY_INDEX];
hour = toDate[HOUR_INDEX];
minute = toDate[MINUTE_INDEX];
second = toDate[SECOND_INDEX];
auto toCalendar = std::unique_ptr<Calendar>(Calendar::createInstance(locale, status));
toCalendar->clear();
toCalendar->set(year, month, day, hour, minute, second);
if (!timeZone.empty()) {
UDate timestamp = toCalendar->getTime(status);
auto zone = std::unique_ptr<TimeZone>(TimeZone::createTimeZone(timeZone.c_str()));
toCalendar->setTimeZone(*zone);
dateIntvFormat->setTimeZone(*zone);
toCalendar->setTime(timestamp, status);
}
FieldPosition pos = 0;
dateIntvFormat->format(*calendar, *toCalendar, dateString, pos, status);
dateString.toUTF8String(result);
return result;
}
void DateTimeFormat::GetResolvedOptions(std::map<std::string, std::string> &map)
{
UErrorCode status = U_ZERO_ERROR;
@ -355,9 +433,8 @@ void DateTimeFormat::GetResolvedOptions(std::map<std::string, std::string> &map)
} else if (!(localeInfo->GetNumberingSystem()).empty()) {
map.insert(std::make_pair("numberingSystem", localeInfo->GetNumberingSystem()));
} else {
NumberingSystem *numSys = NumberingSystem::createInstance(locale, status);
auto numSys = std::unique_ptr<NumberingSystem>(NumberingSystem::createInstance(locale, status));
map.insert(std::make_pair("numberingSystem", numSys->getName()));
delete numSys;
}
GetAdditionalResolvedOptions(map);
}
@ -391,8 +468,14 @@ void DateTimeFormat::GetAdditionalResolvedOptions(std::map<std::string, std::str
if (!second.empty()) {
map.insert(std::make_pair("second", second));
}
if (!fractionalSecondDigits.empty()) {
map.insert(std::make_pair("fractionalSecondDigits", fractionalSecondDigits));
if (!dayPeriod.empty()) {
map.insert(std::make_pair("dayPeriod", dayPeriod));
}
if (!localeMatcher.empty()) {
map.insert(std::make_pair("localeMatcher", localeMatcher));
}
if (!formatMatcher.empty()) {
map.insert(std::make_pair("formatMatcher", formatMatcher));
}
}
@ -471,11 +554,6 @@ std::string DateTimeFormat::GetSecond() const
return second;
}
std::string DateTimeFormat::GetFractionalSecondDigits() const
{
return fractionalSecondDigits;
}
bool DateTimeFormat::Init()
{
SetHwIcuDirectory();
@ -483,4 +561,4 @@ bool DateTimeFormat::Init()
}
} // namespace I18n
} // namespace Global
} // namespace OHOS
} // namespace OHOS

View File

@ -245,4 +245,4 @@ bool LocaleInfo::Init()
}
} // namespace I18n
} // namespace Global
} // namespace OHOS
} // namespace OHOS

View File

@ -16,14 +16,37 @@
#include "ohos/init_data.h"
#include <locale>
#include <codecvt>
#include <iostream>
namespace OHOS {
namespace Global {
namespace I18n {
std::map<std::string, UNumberFormatStyle> NumberFormat::formatStyle = {
{"decimal", UNumberFormatStyle::UNUM_DECIMAL },
{ "currency", UNumberFormatStyle::UNUM_CURRENCY },
{ "percent", UNumberFormatStyle::UNUM_PERCENT }
std::map<std::string, UNumberUnitWidth> NumberFormat::unitStyle = {
{ "long", UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME },
{ "short", UNumberUnitWidth::UNUM_UNIT_WIDTH_SHORT },
{ "narrow", UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW }
};
std::map<std::string, UNumberUnitWidth> NumberFormat::currencyStyle = {
{ "symbol", UNumberUnitWidth::UNUM_UNIT_WIDTH_SHORT },
{ "code", UNumberUnitWidth::UNUM_UNIT_WIDTH_ISO_CODE },
{ "name", UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME },
{ "narrowSymbol", UNumberUnitWidth::UNUM_UNIT_WIDTH_NARROW }
};
std::map<std::string, UNumberSignDisplay> NumberFormat::signAutoStyle = {
{ "auto", UNumberSignDisplay::UNUM_SIGN_AUTO },
{ "never", UNumberSignDisplay::UNUM_SIGN_NEVER },
{ "always", UNumberSignDisplay::UNUM_SIGN_ALWAYS },
{ "exceptZero", UNumberSignDisplay::UNUM_SIGN_EXCEPT_ZERO }
};
std::map<std::string, UNumberSignDisplay> NumberFormat::signAccountingStyle = {
{ "auto", UNumberSignDisplay::UNUM_SIGN_ACCOUNTING },
{ "never", UNumberSignDisplay::UNUM_SIGN_NEVER },
{ "always", UNumberSignDisplay::UNUM_SIGN_ACCOUNTING_ALWAYS },
{ "exceptZero", UNumberSignDisplay::UNUM_SIGN_ACCOUNTING_EXCEPT_ZERO }
};
NumberFormat::NumberFormat(const std::vector<std::string> &localeTags, std::map<std::string, std::string> &configs)
@ -31,7 +54,6 @@ NumberFormat::NumberFormat(const std::vector<std::string> &localeTags, std::map<
UErrorCode status = U_ZERO_ERROR;
auto builder = std::make_unique<icu::LocaleBuilder>();
ParseConfigs(configs);
GetValidLocales();
for (size_t i = 0; i < localeTags.size(); i++) {
std::string curLocale = localeTags[i];
locale = builder->setLanguageTag(icu::StringPiece(curLocale)).build(status);
@ -39,89 +61,172 @@ NumberFormat::NumberFormat(const std::vector<std::string> &localeTags, std::map<
localeInfo = new LocaleInfo(curLocale, configs);
locale = localeInfo->GetLocale();
localeBaseName = localeInfo->GetBaseName();
numberFormat = icu::NumberFormat::createInstance(locale, style, status);
if (numberFormat == nullptr) {
continue;
}
numberFormat = icu::number::NumberFormatter::withLocale(locale);
icu::MeasureUnit::getAvailable(unitArray, MAX_UNIT_NUM, status);
break;
}
}
if (numberFormat == nullptr) {
locale = icu::Locale::getDefault();
localeBaseName = locale.getBaseName();
std::replace(localeBaseName.begin(), localeBaseName.end(), '_', '-');
numberFormat = icu::NumberFormat::createInstance(status);
}
InitProperties();
}
NumberFormat::~NumberFormat()
{
if (numberFormat != nullptr) {
delete numberFormat;
numberFormat = nullptr;
if (localeInfo != nullptr) {
delete localeInfo;
localeInfo = nullptr;
}
}
void NumberFormat::GetValidLocales()
std::set<std::string> NumberFormat::allValidLocales = GetValidLocales();
std::set<std::string> NumberFormat::GetValidLocales()
{
int32_t validCount = 1;
const icu::Locale *validLocales = icu::Locale::getAvailableLocales(validCount);
std::set<std::string> allValidLocales;
for (int i = 0; i < validCount; i++) {
allValidLocales.insert(validLocales[i].getLanguage());
}
return allValidLocales;
}
void NumberFormat::InitProperties()
{
if (!currency.empty()) {
UErrorCode status = U_ZERO_ERROR;
numberFormat->setCurrency(
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.from_bytes(currency).c_str(), status);
numberFormat =
numberFormat.unit(icu::CurrencyUnit(icu::UnicodeString(currency.c_str()).getBuffer(), status));
if (currencyDisplay != UNumberUnitWidth::UNUM_UNIT_WIDTH_SHORT) {
numberFormat = numberFormat.unitWidth(currencyDisplay);
}
}
if (!styleString.empty() && styleString == "percent") {
numberFormat = numberFormat.unit(icu::NoUnit::percent());
}
if (!styleString.empty() && styleString == "unit") {
for (icu::MeasureUnit curUnit : unitArray) {
if (strcmp(curUnit.getSubtype(), unit.c_str()) == 0) {
numberFormat = numberFormat.unit(curUnit);
}
}
numberFormat = numberFormat.unitWidth(unitDisplay);
}
if (!useGrouping.empty()) {
numberFormat->setGroupingUsed(useGrouping == "true");
numberFormat.grouping(useGrouping == "true" ?
UNumberGroupingStrategy::UNUM_GROUPING_AUTO : UNumberGroupingStrategy::UNUM_GROUPING_OFF);
}
if (!minimumIntegerDigits.empty()) {
numberFormat->setMinimumIntegerDigits(std::stoi(minimumIntegerDigits));
if (!currencySign.empty() || !signDisplayString.empty()) {
numberFormat = numberFormat.sign(signDisplay);
}
if (!minimumFractionDigits.empty()) {
numberFormat->setMinimumFractionDigits(std::stoi(minimumFractionDigits));
if (!notationString.empty()) {
numberFormat = numberFormat.notation(notation);
}
if (!maximumFractionDigits.empty()) {
numberFormat->setMaximumFractionDigits(std::stoi(maximumFractionDigits));
InitDigitsProperties();
}
void NumberFormat::InitDigitsProperties()
{
if (!maximumSignificantDigits.empty() || !minimumSignificantDigits.empty()) {
if (!maximumSignificantDigits.empty()) {
numberFormat =
numberFormat.precision(icu::number::Precision::maxSignificantDigits(std::stoi(maximumSignificantDigits)));
}
if (!minimumSignificantDigits.empty()) {
numberFormat =
numberFormat.precision(icu::number::Precision::minSignificantDigits(std::stoi(minimumSignificantDigits)));
}
} else {
if (!minimumIntegerDigits.empty() && std::stoi(minimumIntegerDigits) > 1) {
numberFormat =
numberFormat.integerWidth(icu::number::IntegerWidth::zeroFillTo(std::stoi(minimumIntegerDigits)));
}
if (!minimumFractionDigits.empty()) {
numberFormat =
numberFormat.precision(icu::number::Precision::minFraction(std::stoi(minimumFractionDigits)));
}
if (!maximumFractionDigits.empty()) {
numberFormat =
numberFormat.precision(icu::number::Precision::maxFraction(std::stoi(maximumFractionDigits)));
}
}
}
void NumberFormat::ParseConfigs(std::map<std::string, std::string> &configs)
{
if (configs.count("currency") > 0) {
currency = configs["currency"];
}
if (configs.count("currencySign") > 0) {
currencySign = configs["currencySign"];
if (configs.count("signDisplay") > 0) {
signDisplayString = configs["signDisplay"];
if (signAutoStyle.count(signDisplayString) > 0) {
signDisplay = signAutoStyle[signDisplayString];
}
}
if (configs.count("style") > 0) {
styleString = configs["style"];
if (formatStyle.count(styleString)) {
style = formatStyle[styleString];
}
if (styleString == "unit" && configs.count("unit") > 0) {
unit = configs["unit"];
if (configs.count("unitDisplay") > 0) {
unitDisplayString = configs["unitDisplay"];
unitDisplay = unitStyle[unitDisplayString];
}
}
if (configs.count("numberingSystem")) {
numberingSystem = configs["numberingSystem"];
if (styleString == "currency" && configs.count("currency") > 0) {
currency = configs["currency"];
if (configs.count("currencySign") > 0) {
currencySign = configs["currencySign"];
if (configs["currencySign"] != "accounting" && !signDisplayString.empty()) {
signDisplay = signAccountingStyle[signDisplayString];
}
}
if (configs.count("currencyDisplay") > 0 && currencyStyle.count(configs["currencyDisplay"]) > 0) {
currencyDisplayString = configs["currencyDisplay"];
currencyDisplay = currencyStyle[currencyDisplayString];
}
}
if (configs.count("useGrouping")) {
useGrouping = configs["useGrouping"];
if (configs.count("notation") > 0) {
notationString = configs["notation"];
if (notationString == "scientific") {
notation = icu::number::Notation::scientific();
} else if (notationString == "engineering") {
notation = icu::number::Notation::engineering();
}
if (notationString == "compact" && configs.count("compactDisplay") > 0) {
compactDisplay = configs["compactDisplay"];
if (compactDisplay == "long") {
notation = icu::number::Notation::compactLong();
} else {
notation = icu::number::Notation::compactShort();
}
}
}
if (configs.count("minimumIntegerDigits")) {
ParseDigitsConfigs(configs);
}
void NumberFormat::ParseDigitsConfigs(std::map<std::string, std::string> &configs)
{
if (configs.count("minimumIntegerDigits") > 0) {
minimumIntegerDigits = configs["minimumIntegerDigits"];
}
if (configs.count("minimumFractionDigits")) {
if (configs.count("minimumFractionDigits") > 0) {
minimumFractionDigits = configs["minimumFractionDigits"];
}
if (configs.count("maximumFractionDigits")) {
if (configs.count("maximumFractionDigits") > 0) {
maximumFractionDigits = configs["maximumFractionDigits"];
}
if (configs.count("minimumSignificantDigits") > 0) {
minimumSignificantDigits = configs["minimumSignificantDigits"];
}
if (configs.count("maximumSignificantDigits") > 0) {
maximumSignificantDigits = configs["maximumSignificantDigits"];
}
if (configs.count("numberingSystem") > 0) {
numberingSystem = configs["numberingSystem"];
}
if (configs.count("useGrouping") > 0) {
useGrouping = configs["useGrouping"];
}
if (configs.count("localeMatcher") > 0) {
localeMatcher = configs["localeMatcher"];
}
}
bool NumberFormat::icuInitialized = NumberFormat::Init();
@ -129,15 +234,13 @@ bool NumberFormat::icuInitialized = NumberFormat::Init();
std::string NumberFormat::Format(double number)
{
std::string result;
icu::UnicodeString numberString;
numberFormat->format(number, numberString);
numberString.toUTF8String(result);
UErrorCode status = U_ZERO_ERROR;
numberFormat.formatDouble(number, status).toString(status).toUTF8String(result);
return result;
}
void NumberFormat::GetResolvedOptions(std::map<std::string, std::string> &map)
{
UErrorCode status = U_ZERO_ERROR;
map.insert(std::make_pair("locale", localeBaseName));
if (!styleString.empty()) {
map.insert(std::make_pair("style", styleString));
@ -148,14 +251,34 @@ void NumberFormat::GetResolvedOptions(std::map<std::string, std::string> &map)
if (!currencySign.empty()) {
map.insert(std::make_pair("currencySign", currencySign));
}
if (!currencyDisplayString.empty()) {
map.insert(std::make_pair("currencyDisplay", currencyDisplayString));
}
if (!signDisplayString.empty()) {
map.insert(std::make_pair("signDisplaysignDisplay", signDisplayString));
}
if (!compactDisplay.empty()) {
map.insert(std::make_pair("compactDisplay", compactDisplay));
}
if (!unitDisplayString.empty()) {
map.insert(std::make_pair("unitDisplay", unitDisplayString));
}
if (!unit.empty()) {
map.insert(std::make_pair("unit", unit));
}
GetDigitsResolvedOptions(map);
}
void NumberFormat::GetDigitsResolvedOptions(std::map<std::string, std::string> &map)
{
UErrorCode status = U_ZERO_ERROR;
if (!numberingSystem.empty()) {
map.insert(std::make_pair("numberingSystem", numberingSystem));
} else if (!(localeInfo->GetNumberingSystem()).empty()) {
map.insert(std::make_pair("numberingSystem", localeInfo->GetNumberingSystem()));
} else {
icu::NumberingSystem *numSys = icu::NumberingSystem::createInstance(locale, status);
auto numSys = std::unique_ptr<icu::NumberingSystem>(icu::NumberingSystem::createInstance(locale, status));
map.insert(std::make_pair("numberingSystem", numSys->getName()));
delete numSys;
}
if (!useGrouping.empty()) {
map.insert(std::make_pair("useGrouping", useGrouping));
@ -169,54 +292,80 @@ void NumberFormat::GetResolvedOptions(std::map<std::string, std::string> &map)
if (!maximumFractionDigits.empty()) {
map.insert(std::make_pair("maximumFractionDigits", maximumFractionDigits));
}
if (!minimumSignificantDigits.empty()) {
map.insert(std::make_pair("minimumSignificantDigits", minimumSignificantDigits));
}
if (!maximumSignificantDigits.empty()) {
map.insert(std::make_pair("maximumSignificantDigits", maximumSignificantDigits));
}
if (!localeMatcher.empty()) {
map.insert(std::make_pair("localeMatcher", localeMatcher));
}
if (!notationString.empty()) {
map.insert(std::make_pair("notation", notationString));
}
}
std::string NumberFormat::GetCurrency()
std::string NumberFormat::GetCurrency() const
{
return currency;
}
std::string NumberFormat::GetCurrencySign()
std::string NumberFormat::GetCurrencySign() const
{
return currencySign;
}
std::string NumberFormat::GetStyle()
std::string NumberFormat::GetStyle() const
{
return styleString;
}
std::string NumberFormat::GetNumberingSystem()
std::string NumberFormat::GetNumberingSystem() const
{
return numberingSystem;
}
std::string NumberFormat::GetUseGrouping()
std::string NumberFormat::GetUseGrouping() const
{
return useGrouping;
}
std::string NumberFormat::GetMinimumIntegerDigits()
std::string NumberFormat::GetMinimumIntegerDigits() const
{
return minimumIntegerDigits;
}
std::string NumberFormat::GetMinimumFractionDigits()
std::string NumberFormat::GetMinimumFractionDigits() const
{
return minimumFractionDigits;
}
std::string NumberFormat::GetMaximumFractionDigits()
std::string NumberFormat::GetMaximumFractionDigits() const
{
return maximumFractionDigits;
}
std::string NumberFormat::GetMinimumSignificantDigits() const
{
return minimumSignificantDigits;
}
std::string NumberFormat::GetMaximumSignificantDigits() const
{
return maximumSignificantDigits;
}
std::string NumberFormat::GetLocaleMatcher() const
{
return localeMatcher;
}
bool NumberFormat::Init()
{
SetHwIcuDirectory();
return true;
}
} // namespace I18n
} // namespace Global
} // namespace OHOS

View File

@ -51,29 +51,28 @@ void IntlTest::TearDown(void)
* @tc.desc: Test Intl DateTimeFormat.format
* @tc.type: FUNC
*/
HWTEST_F(IntlTest, IntlFuncTest001, TestSize.Level1)
HWTEST_F(IntlTest, IntlFuncTest001, TestSize.Level1)
{
string locale = "zh-CN-u-hc-h12";
string expects = "公元2021年4月14日星期三 北美太平洋夏令时间 上午12:05:03";
string expects = "公元2021年4月14日星期三 下午3:05:03";
vector<string> locales;
locales.push_back("jessie");
locales.push_back(locale);
map<string, string> options = { {"year", "numeric"},
{"month", "long"},
{"day", "numeric"},
{"hour", "numeric"},
{"minute", "2-digit"},
{"second", "numeric"},
{"weekday", "long"},
{"era", "short"},
{"timeZone", "America/Los_Angeles"},
{"timeZoneName", "long"}};
map<string, string> options = { { "year", "numeric" },
{ "month", "long" },
{ "day", "numeric" },
{ "hour", "numeric" },
{ "minute", "2-digit" },
{ "second", "numeric" },
{ "weekday", "long" },
{ "era", "short"} };
DateTimeFormat *dateFormat = new (std::nothrow) DateTimeFormat(locales, options);
if (dateFormat == nullptr) {
EXPECT_TRUE(false);
return;
}
string out = dateFormat->Format(2021, 3, 14, 15, 5, 3);
int64_t date[] = { 2021, 3, 14, 15, 5, 3 };
string out = dateFormat->Format(date);
EXPECT_EQ(out, expects);
EXPECT_EQ(dateFormat->GetYear(), "numeric");
EXPECT_EQ(dateFormat->GetMonth(), "long");
@ -84,20 +83,6 @@ HWTEST_F(IntlTest, IntlFuncTest001, TestSize.Level1)
EXPECT_EQ(dateFormat->GetWeekday(), "long");
EXPECT_EQ(dateFormat->GetEra(), "short");
EXPECT_EQ(dateFormat->GetHourCycle(), "h12");
map<string, string> resolvedOptions = {};
dateFormat->GetResolvedOptions(resolvedOptions);
string str="{";
typename map<string,string>::iterator it = resolvedOptions.begin();
for (;it != resolvedOptions.end();it++) {
str += "{";
str += it->first + ": " + it->second;
str += "}";
}
str += "}";
string optionsString = "{{calendar: gregorian}{day: numeric}{era: short}{hour: numeric}{hourCycle: h12}";
optionsString += "{locale: zh-CN}{minute: 2-digit}{month: long}{numberingSystem: latn}{second: numeric}";
optionsString += "{timeZone: America/Los_Angeles}{timeZoneName: long}{weekday: long}{year: numeric}}";
EXPECT_EQ(str, optionsString);
delete dateFormat;
}
@ -106,12 +91,12 @@ HWTEST_F(IntlTest, IntlFuncTest001, TestSize.Level1)
* @tc.desc: Test Intl LocaleInfo
* @tc.type: FUNC
*/
HWTEST_F(IntlTest, IntlFuncTest002, TestSize.Level1)
HWTEST_F(IntlTest, IntlFuncTest002, TestSize.Level1)
{
string locale = "ja-Jpan-JP-u-ca-japanese-hc-h12-co-emoji";
map<string, string> options = { {"hourCycle", "h11"},
{"numeric", "true"},
{"numberingSystem", "jpan"}};
map<string, string> options = { { "hourCycle", "h11" },
{ "numeric", "true" },
{ "numberingSystem", "jpan" } };
LocaleInfo *loc = new (std::nothrow) LocaleInfo(locale, options);
if (loc == nullptr) {
EXPECT_TRUE(false);
@ -136,7 +121,7 @@ HWTEST_F(IntlTest, IntlFuncTest002, TestSize.Level1)
* @tc.desc: Test Intl LocaleInfo
* @tc.type: FUNC
*/
HWTEST_F(IntlTest, IntlFuncTest003, TestSize.Level1)
HWTEST_F(IntlTest, IntlFuncTest003, TestSize.Level1)
{
string locale = "en-GB";
LocaleInfo *loc = new (std::nothrow) LocaleInfo(locale);
@ -160,38 +145,58 @@ HWTEST_F(IntlTest, IntlFuncTest003, TestSize.Level1)
* @tc.desc: Test Intl DateTimeFormat.format
* @tc.type: FUNC
*/
HWTEST_F(IntlTest, IntlFuncTest004, TestSize.Level1)
HWTEST_F(IntlTest, IntlFuncTest004, TestSize.Level1)
{
string locale = "en-GB";
string expects = "14 April 2021 at 15:05";
string expects = "14 April 2021, 15:05 5 May 2021, 10:05";
vector<string> locales;
locales.push_back(locale);
string dateStyle = "long";
string timeStyle = "short";
map<string, string> options = { {"dateStyle", dateStyle},
{"timeStyle", timeStyle}};
map<string, string> options = { { "dateStyle", dateStyle },
{ "timeStyle", timeStyle } };
DateTimeFormat *dateFormat = new (std::nothrow) DateTimeFormat(locales, options);
if (dateFormat == nullptr) {
EXPECT_TRUE(false);
return;
}
string out = dateFormat->Format(2021, 3, 14, 15, 5, 3);
int64_t date1[] = {2021, 3, 14, 15, 5, 3};
int64_t date2[] = {2021, 4, 5, 10, 5, 3};
string out = dateFormat->FormatRange(date1, date2);
EXPECT_EQ(out, expects);
EXPECT_EQ(dateFormat->GetDateStyle(), dateStyle);
EXPECT_EQ(dateFormat->GetTimeStyle(), timeStyle);
map<string, string> resolvedOptions = {};
dateFormat->GetResolvedOptions(resolvedOptions);
string str="{";
typename map<string,string>::iterator it = resolvedOptions.begin();
for (;it != resolvedOptions.end();it++) {
str += "{";
str += it->first + ": " + it->second;
str += "}";
delete dateFormat;
}
/**
* @tc.name: IntlFuncTest001
* @tc.desc: Test Intl DateTimeFormat.format
* @tc.type: FUNC
*/
HWTEST_F(IntlTest, IntlFuncTest006, TestSize.Level1)
{
string locale = "ja";
string expects = "2021年4月14日水曜日";
vector<string> locales;
locales.push_back(locale);
map<string, string> options = { { "year", "numeric" },
{ "month", "long" },
{ "day", "numeric" },
{ "weekday", "long"} };
DateTimeFormat *dateFormat = new (std::nothrow) DateTimeFormat(locales, options);
if (dateFormat == nullptr) {
EXPECT_TRUE(false);
return;
}
str += "}";
std::string optionsString = "{{calendar: gregorian}{dateStyle: long}{locale: en-GB}{numberingSystem: latn}";
optionsString += "{timeStyle: short}{timeZone: Asia/Shanghai}}";
EXPECT_EQ(str, optionsString);
int64_t date[] = { 2021, 3, 14, 15, 5, 3 };
string out = dateFormat->Format(date);
EXPECT_EQ(out, expects);
int64_t date1[] = {2021, 3, 14, 15, 5, 3};
int64_t date2[] = {2021, 4, 5, 10, 5, 3};
expects = "2021/04/14水曜日2021/05/05水曜日";
out = dateFormat->FormatRange(date1, date2);
EXPECT_EQ(out, expects);
delete dateFormat;
}
@ -200,10 +205,10 @@ HWTEST_F(IntlTest, IntlFuncTest004, TestSize.Level1)
* @tc.desc: Test Intl DateTimeFormat.format
* @tc.type: FUNC
*/
HWTEST_F(IntlTest, IntlFuncTest005, TestSize.Level1)
HWTEST_F(IntlTest, IntlFuncTest005, TestSize.Level1)
{
string locale = "en-IN";
string expects = "€01,23,456.79";
string expects = "+1,23,456.79 euros";
vector<string> locales;
locales.push_back(locale);
string useGrouping = "true";
@ -211,11 +216,12 @@ HWTEST_F(IntlTest, IntlFuncTest005, TestSize.Level1)
string maximumFractionDigits = "2";
string style = "currency";
string currency = "EUR";
map<string, string> options = { {"useGrouping", useGrouping},
{"minimumIntegerDigits", minimumIntegerDigits},
{"maximumFractionDigits", maximumFractionDigits},
{"style", style},
{"currency", currency}};
map<string, string> options = { { "useGrouping", useGrouping },
{ "style", style },
{ "currency", currency },
{ "currencyDisplay", "name" },
{ "currencySign", "accounting" },
{ "signDisplay", "always" } };
NumberFormat *numFmt = new (std::nothrow) NumberFormat(locales, options);
if (numFmt == nullptr) {
EXPECT_TRUE(false);
@ -224,10 +230,237 @@ HWTEST_F(IntlTest, IntlFuncTest005, TestSize.Level1)
string out = numFmt->Format(123456.789);
EXPECT_EQ(out, expects);
EXPECT_EQ(numFmt->GetUseGrouping(), useGrouping);
EXPECT_EQ(numFmt->GetMinimumIntegerDigits(), minimumIntegerDigits);
EXPECT_EQ(numFmt->GetMaximumFractionDigits(), maximumFractionDigits);
EXPECT_EQ(numFmt->GetStyle(), style);
EXPECT_EQ(numFmt->GetCurrency(), currency);
delete numFmt;
}
/**
* @tc.name: IntlFuncTest005
* @tc.desc: Test Intl DateTimeFormat.format
* @tc.type: FUNC
*/
HWTEST_F(IntlTest, IntlFuncTest007, TestSize.Level1)
{
string locale = "zh-CN";
string expects = "0,123,456.79米";
vector<string> locales;
locales.push_back("ban");
locales.push_back(locale);
string minimumIntegerDigits = "7";
string maximumFractionDigits = "2";
string style = "unit";
map<string, string> options = { { "style", style },
{ "minimumIntegerDigits", minimumIntegerDigits },
{ "maximumFractionDigits", maximumFractionDigits },
{ "unit", "meter" },
{ "unitDisplay", "long"} };
NumberFormat *numFmt = new (std::nothrow) NumberFormat(locales, options);
if (numFmt == nullptr) {
EXPECT_TRUE(false);
return;
}
string out = numFmt->Format(123456.789);
EXPECT_EQ(out, expects);
EXPECT_EQ(numFmt->GetStyle(), style);
delete numFmt;
}
/**
* @tc.name: IntlFuncTest005
* @tc.desc: Test Intl DateTimeFormat.format
* @tc.type: FUNC
*/
HWTEST_F(IntlTest, IntlFuncTest008, TestSize.Level1)
{
string locale = "en-CN";
string expects = "0,123,456.79%";
vector<string> locales;
locales.push_back(locale);
string minimumIntegerDigits = "7";
string maximumFractionDigits = "2";
string style = "percent";
map<string, string> options = { { "style", style },
{ "minimumIntegerDigits", minimumIntegerDigits },
{ "maximumFractionDigits", maximumFractionDigits } };
NumberFormat *numFmt = new (std::nothrow) NumberFormat(locales, options);
if (numFmt == nullptr) {
EXPECT_TRUE(false);
return;
}
string out = numFmt->Format(123456.789);
EXPECT_EQ(out, expects);
EXPECT_EQ(numFmt->GetStyle(), style);
delete numFmt;
}
/**
* @tc.name: IntlFuncTest005
* @tc.desc: Test Intl DateTimeFormat.format
* @tc.type: FUNC
*/
HWTEST_F(IntlTest, IntlFuncTest009, TestSize.Level1)
{
string locale = "en-CN";
string expects = "0,123,456.79";
vector<string> locales;
locales.push_back(locale);
string minimumIntegerDigits = "7";
string maximumFractionDigits = "2";
string style = "decimal";
map<string, string> options = { { "style", style },
{ "minimumIntegerDigits", minimumIntegerDigits },
{ "maximumFractionDigits", maximumFractionDigits } };
NumberFormat *numFmt = new (std::nothrow) NumberFormat(locales, options);
if (numFmt == nullptr) {
EXPECT_TRUE(false);
return;
}
string out = numFmt->Format(123456.789);
EXPECT_EQ(out, expects);
EXPECT_EQ(numFmt->GetStyle(), style);
delete numFmt;
}
/**
* @tc.name: IntlFuncTest005
* @tc.desc: Test Intl DateTimeFormat.format
* @tc.type: FUNC
*/
HWTEST_F(IntlTest, IntlFuncTest010, TestSize.Level1)
{
string locale = "en-CN";
string expects = "1.234568E5";
vector<string> locales;
locales.push_back(locale);
string style = "decimal";
map<string, string> options = { { "style", style },
{ "notation", "scientific" } };
NumberFormat *numFmt = new (std::nothrow) NumberFormat(locales, options);
if (numFmt == nullptr) {
EXPECT_TRUE(false);
return;
}
string out = numFmt->Format(123456.789);
EXPECT_EQ(out, expects);
EXPECT_EQ(numFmt->GetStyle(), style);
delete numFmt;
}
/**
* @tc.name: IntlFuncTest005
* @tc.desc: Test Intl DateTimeFormat.format
* @tc.type: FUNC
*/
HWTEST_F(IntlTest, IntlFuncTest011, TestSize.Level1)
{
string locale = "en-CN";
string expects = "123 thousand";
vector<string> locales;
locales.push_back(locale);
string style = "decimal";
map<string, string> options = { { "style", style },
{ "notation", "compact" },
{ "compactDisplay", "long" } };
NumberFormat *numFmt = new (std::nothrow) NumberFormat(locales, options);
if (numFmt == nullptr) {
EXPECT_TRUE(false);
return;
}
string out = numFmt->Format(123456.789);
EXPECT_EQ(out, expects);
EXPECT_EQ(numFmt->GetStyle(), style);
delete numFmt;
}
/**
* @tc.name: IntlFuncTest002
* @tc.desc: Test Intl LocaleInfo
* @tc.type: FUNC
*/
HWTEST_F(IntlTest, IntlFuncTest0012, TestSize.Level1)
{
string locale = "en";
map<string, string> options = {};
vector<string> locales;
locales.push_back(locale);
std::string expects = "4/14/21";
DateTimeFormat *dateFormat = new (std::nothrow) DateTimeFormat(locales, options);
if (dateFormat == nullptr) {
EXPECT_TRUE(false);
return;
}
int64_t date[] = {2021, 3, 14, 15, 5, 3};
string out = dateFormat->Format(date);
EXPECT_EQ(out, expects);
delete dateFormat;
}
/**
* @tc.name: IntlFuncTest002
* @tc.desc: Test Intl LocaleInfo
* @tc.type: FUNC
*/
HWTEST_F(IntlTest, IntlFuncTest0013, TestSize.Level1)
{
string locale = "en-CN";
vector<string> locales;
locales.push_back(locale);
map<string, string> options = {};
std::string expects = "123,456.789";
NumberFormat *numFmt = new (std::nothrow) NumberFormat(locales, options);
if (numFmt == nullptr) {
EXPECT_TRUE(false);
return;
}
string out = numFmt->Format(123456.789);
EXPECT_EQ(out, expects);
delete numFmt;
}
/**
* @tc.name: IntlFuncTest002
* @tc.desc: Test Intl LocaleInfo
* @tc.type: FUNC
*/
HWTEST_F(IntlTest, IntlFuncTest0014, TestSize.Level1)
{
string locale = "zh-CN-u-hc-h12";
string expects = "北美太平洋夏令时间";
vector<string> locales;
locales.push_back("jessie");
locales.push_back(locale);
map<string, string> options = { { "timeZone", "America/Los_Angeles" }, { "timeZoneName", "long" } };
DateTimeFormat *dateFormat = new (std::nothrow) DateTimeFormat(locales, options);
if (dateFormat == nullptr) {
EXPECT_TRUE(false);
return;
}
int64_t date[] = { 2021, 3, 14, 15, 5, 3 };
string out = dateFormat->Format(date);
EXPECT_TRUE(out.find(expects) != out.npos);
delete dateFormat;
}
/**
* @tc.name: IntlFuncTest002
* @tc.desc: Test Intl LocaleInfo
* @tc.type: FUNC
*/
HWTEST_F(IntlTest, IntlFuncTest0015, TestSize.Level1)
{
string locale = "zh-CN-u-hc-h12";
vector<string> locales;
locales.push_back("jessie");
locales.push_back(locale);
map<string, string> options = { { "timeZone", "America/Los_Angeles" }, { "timeZoneName", "long" } };
DateTimeFormat *dateFormat = new (std::nothrow) DateTimeFormat(locales, options);
if (dateFormat == nullptr) {
EXPECT_TRUE(false);
return;
}
EXPECT_EQ(dateFormat->GetTimeZone(), "America/Los_Angeles");
EXPECT_EQ(dateFormat->GetTimeZoneName(), "long");
delete dateFormat;
}
}

View File

@ -21,4 +21,18 @@ int IntlFuncTest002();
int IntlFuncTest003();
int IntlFuncTest004();
int IntlFuncTest005();
int IntlFuncTest006();
int IntlFuncTest007();
int IntlFuncTest008();
int IntlFuncTest009();
int IntlFuncTest0010();
int IntlFuncTest0011();
int IntlFuncTest0012();
int IntlFuncTest0013();
int IntlFuncTest0014();
int IntlFuncTest0015();
int IntlFuncTest0016();
int IntlFuncTest0017();
int IntlFuncTest0018();
int IntlFuncTest0019();
#endif

View File

@ -179,6 +179,21 @@ export interface DateTimeOptions {
* Indicates the timezone name.
*/
timeZoneName: string
/**
* Indicates the day period format.
*/
dayPeriod: string
/**
* Indicates the locale matching algorithm.
*/
localeMatcher: string
/**
* Indicates the format matching algorithm.
*/
foramtMatcher: string
}
/**
@ -216,6 +231,16 @@ export class DateTimeFormat {
*/
format(date: Date): string;
/**
* Obtains the formatted date strings of a date range.
*
* @param startDate Indicates the start date of the date range.
* @param endDate Indicates the end date of the date range.
* @return Returns a date string formatted based on the specified locale.
* @since 6
*/
formatRange(startDate: Date, endDate: Date): string;
/**
* Obtains the options of the DateTimeFormat object.
*
@ -239,6 +264,46 @@ export interface NumberOptions {
*/
currency: string
/**
* Indicates the currency sign.
*/
currencySign: string
/**
* Indicates the currency display format.
*/
currencyDisplay: string
/**
* Indicates the unit.
*/
unit: string
/**
* Indicates the unit display format.
*/
unitDisplay: string
/**
* Indicates the sign display format.
*/
signDisplay: string
/**
* Indicates the compact display format.
*/
compactDisplay: string
/**
* Indicates the notation.
*/
notation: string
/**
* Indicates the locale matching algorithm.
*/
localeMatcher: string
/**
* Indicates the style.
*/
@ -268,6 +333,16 @@ export interface NumberOptions {
* Indicates the maximum fraction digits.
*/
maximumFractionDigits: string
/**
* Indicates the minimum siginificant digits.
*/
minimumSiginificantDigits: string
/**
* Indicates the maximum siginificant digits.
*/
maximumSiginificantDigits: string
}
/**
@ -280,4 +355,4 @@ export class NumberFormat {
resolvedOptions(): Object;
}
}
export default intl;
export default intl;

View File

@ -65,17 +65,18 @@ private:
static napi_value ToString(napi_env env, napi_callback_info info);
static napi_value FormatDateTime(napi_env env, napi_callback_info info);
static napi_value FormatDateTimeRange(napi_env env, napi_callback_info info);
static napi_value GetDateTimeResolvedOptions(napi_env env, napi_callback_info info);
static napi_value GetNumberResolvedOptions(napi_env env, napi_callback_info info);
static napi_value FormatNumber(napi_env env, napi_callback_info info);
static int64_t GetYear(napi_env env, napi_value *argv);
static int64_t GetMonth(napi_env env, napi_value *argv);
static int64_t GetDay(napi_env env, napi_value *argv);
static int64_t GetHour(napi_env env, napi_value *argv);
static int64_t GetMinute(napi_env env, napi_value *argv);
static int64_t GetSecond(napi_env env, napi_value *argv);
static int64_t GetYear(napi_env env, napi_value *argv, int index);
static int64_t GetMonth(napi_env env, napi_value *argv, int index);
static int64_t GetDay(napi_env env, napi_value *argv, int index);
static int64_t GetHour(napi_env env, napi_value *argv, int index);
static int64_t GetMinute(napi_env env, napi_value *argv, int index);
static int64_t GetSecond(napi_env env, napi_value *argv, int index);
bool InitLocaleContext(napi_env env, napi_callback_info info, const std::string localeTag,
std::map<std::string, std::string> &map);
bool InitDateTimeFormatContext(napi_env env, napi_callback_info info, std::vector<std::string> localeTags,

View File

@ -86,6 +86,7 @@ napi_value IntlAddon::InitDateTimeFormat(napi_env env, napi_value exports)
napi_status status;
napi_property_descriptor properties[] = {
DECLARE_NAPI_FUNCTION("format", FormatDateTime),
DECLARE_NAPI_FUNCTION("formatRange", FormatDateTimeRange),
DECLARE_NAPI_FUNCTION("resolvedOptions", GetDateTimeResolvedOptions)
};
@ -181,6 +182,9 @@ void GetDateOptionValues(napi_env env, napi_value options, std::map<std::string,
GetOptionValue(env, options, "hour", map);
GetOptionValue(env, options, "minute", map);
GetOptionValue(env, options, "second", map);
GetOptionValue(env, options, "localeMatcher", map);
GetOptionValue(env, options, "formatMatcher", map);
GetOptionValue(env, options, "dayPeriod", map);
}
napi_value IntlAddon::LocaleConstructor(napi_env env, napi_callback_info info)
@ -338,12 +342,12 @@ bool IntlAddon::InitDateTimeFormatContext(napi_env env, napi_callback_info info,
napi_value IntlAddon::FormatDateTime(napi_env env, napi_callback_info info)
{
GET_PARAMS(env, info, 1); // Need to get one parameter of a date object to format.
int64_t year = GetYear(env, argv);
int64_t month = GetMonth(env, argv);
int64_t day = GetDay(env, argv);
int64_t hour = GetHour(env, argv);
int64_t minute = GetMinute(env, argv);
int64_t second = GetSecond(env, argv);
int64_t year = GetYear(env, argv, 0);
int64_t month = GetMonth(env, argv, 0);
int64_t day = GetDay(env, argv, 0);
int64_t hour = GetHour(env, argv, 0);
int64_t minute = GetMinute(env, argv, 0);
int64_t second = GetSecond(env, argv, 0);
if (year == -1 || month == -1 || day == -1 || hour == -1 || minute == -1 || second == -1) {
return nullptr;
}
@ -353,7 +357,8 @@ napi_value IntlAddon::FormatDateTime(napi_env env, napi_callback_info info)
HiLog::Error(LABEL, "Get DateTimeFormat object failed");
return nullptr;
}
std::string value = obj->datefmt_->Format(year, month, day, hour, minute, second);
int64_t date[] = { year, month, day, hour, minute, second };
std::string value = obj->datefmt_->Format(date);
napi_value result;
status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
if (status != napi_ok) {
@ -363,6 +368,42 @@ napi_value IntlAddon::FormatDateTime(napi_env env, napi_callback_info info)
return result;
}
napi_value IntlAddon::FormatDateTimeRange(napi_env env, napi_callback_info info)
{
GET_PARAMS(env, info, 2); // Need to get two parameter of date objects to format.
int64_t firstYear = GetYear(env, argv, 0);
int64_t firstMonth = GetMonth(env, argv, 0);
int64_t firstDay = GetDay(env, argv, 0);
int64_t firstHour = GetHour(env, argv, 0);
int64_t firstMinute = GetMinute(env, argv, 0);
int64_t firstSecond = GetSecond(env, argv, 0);
int64_t firstDate[] = { firstYear, firstMonth, firstDay, firstHour, firstMinute, firstSecond };
int64_t secondYear = GetYear(env, argv, 1);
int64_t secondMonth = GetMonth(env, argv, 1);
int64_t secondDay = GetDay(env, argv, 1);
int64_t secondHour = GetHour(env, argv, 1);
int64_t secondMinute = GetMinute(env, argv, 1);
int64_t secondSecond = GetSecond(env, argv, 1);
int64_t secondDate[] = { secondYear, secondMonth, secondDay, secondHour, secondMinute, secondSecond };
if (firstYear == -1 || firstMonth == -1 || firstDay == -1 || firstHour == -1 || firstMinute == -1 ||
firstSecond == -1) {
return nullptr;
}
IntlAddon *obj = nullptr;
napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
if (status != napi_ok || obj == nullptr || obj->datefmt_ == nullptr) {
HiLog::Error(LABEL, "Get DateTimeFormat object failed");
return nullptr;
}
std::string value = obj->datefmt_->FormatRange(firstDate, secondDate);
napi_value result;
status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
if (status != napi_ok) {
HiLog::Error(LABEL, "Create format string failed");
return nullptr;
}
return result;
}
napi_value IntlAddon::NumberFormatConstructor(napi_env env, napi_callback_info info)
{
// Need to get one parameter of a locale in string format to create DateTimeFormat object.
@ -389,12 +430,22 @@ napi_value IntlAddon::NumberFormatConstructor(napi_env env, napi_callback_info i
std::map<std::string, std::string> map = {};
if (argv[1] != nullptr) {
GetOptionValue(env, argv[1], "currency", map);
GetOptionValue(env, argv[1], "currencySign", map);
GetOptionValue(env, argv[1], "currencyDisplay", map);
GetOptionValue(env, argv[1], "unit", map);
GetOptionValue(env, argv[1], "unitDisplay", map);
GetOptionValue(env, argv[1], "compactDisplay", map);
GetOptionValue(env, argv[1], "signDisplay", map);
GetOptionValue(env, argv[1], "localeMatcher", map);
GetOptionValue(env, argv[1], "style", map);
GetOptionValue(env, argv[1], "numberingSystem", map);
GetOptionValue(env, argv[1], "notation", map);
GetBoolOptionValue(env, argv[1], "useGrouping", map);
GetOptionValue(env, argv[1], "minimumIntegerDigits", map);
GetOptionValue(env, argv[1], "minimumFractionDigits", map);
GetOptionValue(env, argv[1], "maximumFractionDigits", map);
GetOptionValue(env, argv[1], "minimumSignificantDigits", map);
GetOptionValue(env, argv[1], "maximumSignificantDigits", map);
}
std::unique_ptr<IntlAddon> obj = std::make_unique<IntlAddon>();
@ -434,16 +485,16 @@ bool IntlAddon::InitNumberFormatContext(napi_env env, napi_callback_info info, s
return numberfmt_ != nullptr;
}
int64_t IntlAddon::GetYear(napi_env env, napi_value *argv)
int64_t IntlAddon::GetYear(napi_env env, napi_value *argv, int index)
{
napi_value funcGetDateInfo;
napi_status status = napi_get_named_property(env, argv[0], "getFullYear", &funcGetDateInfo);
napi_status status = napi_get_named_property(env, argv[index], "getFullYear", &funcGetDateInfo);
if (status != napi_ok) {
HiLog::Error(LABEL, "Get year property failed");
return -1;
}
napi_value ret_value;
status = napi_call_function(env, argv[0], funcGetDateInfo, 0, nullptr, &ret_value);
status = napi_call_function(env, argv[index], funcGetDateInfo, 0, nullptr, &ret_value);
if (status != napi_ok) {
HiLog::Error(LABEL, "Get year function failed");
return -1;
@ -457,16 +508,16 @@ int64_t IntlAddon::GetYear(napi_env env, napi_value *argv)
return year;
}
int64_t IntlAddon::GetMonth(napi_env env, napi_value *argv)
int64_t IntlAddon::GetMonth(napi_env env, napi_value *argv, int index)
{
napi_value funcGetDateInfo;
napi_status status = napi_get_named_property(env, argv[0], "getMonth", &funcGetDateInfo);
napi_status status = napi_get_named_property(env, argv[index], "getMonth", &funcGetDateInfo);
if (status != napi_ok) {
HiLog::Error(LABEL, "Get month property failed");
return -1;
}
napi_value ret_value;
status = napi_call_function(env, argv[0], funcGetDateInfo, 0, nullptr, &ret_value);
status = napi_call_function(env, argv[index], funcGetDateInfo, 0, nullptr, &ret_value);
if (status != napi_ok) {
HiLog::Error(LABEL, "Get month function failed");
return -1;
@ -480,16 +531,16 @@ int64_t IntlAddon::GetMonth(napi_env env, napi_value *argv)
return month;
}
int64_t IntlAddon::GetDay(napi_env env, napi_value *argv)
int64_t IntlAddon::GetDay(napi_env env, napi_value *argv, int index)
{
napi_value funcGetDateInfo;
napi_status status = napi_get_named_property(env, argv[0], "getDate", &funcGetDateInfo);
napi_status status = napi_get_named_property(env, argv[index], "getDate", &funcGetDateInfo);
if (status != napi_ok) {
HiLog::Error(LABEL, "Get day property failed");
return -1;
}
napi_value ret_value;
status = napi_call_function(env, argv[0], funcGetDateInfo, 0, nullptr, &ret_value);
status = napi_call_function(env, argv[index], funcGetDateInfo, 0, nullptr, &ret_value);
if (status != napi_ok) {
HiLog::Error(LABEL, "Get day function failed");
return -1;
@ -503,16 +554,16 @@ int64_t IntlAddon::GetDay(napi_env env, napi_value *argv)
return day;
}
int64_t IntlAddon::GetHour(napi_env env, napi_value *argv)
int64_t IntlAddon::GetHour(napi_env env, napi_value *argv, int index)
{
napi_value funcGetDateInfo;
napi_status status = napi_get_named_property(env, argv[0], "getHours", &funcGetDateInfo);
napi_status status = napi_get_named_property(env, argv[index], "getHours", &funcGetDateInfo);
if (status != napi_ok) {
HiLog::Error(LABEL, "Get hour property failed");
return -1;
}
napi_value ret_value;
status = napi_call_function(env, argv[0], funcGetDateInfo, 0, nullptr, &ret_value);
status = napi_call_function(env, argv[index], funcGetDateInfo, 0, nullptr, &ret_value);
if (status != napi_ok) {
HiLog::Error(LABEL, "Get hour function failed");
return -1;
@ -526,16 +577,16 @@ int64_t IntlAddon::GetHour(napi_env env, napi_value *argv)
return hour;
}
int64_t IntlAddon::GetMinute(napi_env env, napi_value *argv)
int64_t IntlAddon::GetMinute(napi_env env, napi_value *argv, int index)
{
napi_value funcGetDateInfo;
napi_status status = napi_get_named_property(env, argv[0], "getMinutes", &funcGetDateInfo);
napi_status status = napi_get_named_property(env, argv[index], "getMinutes", &funcGetDateInfo);
if (status != napi_ok) {
HiLog::Error(LABEL, "Get minute property failed");
return -1;
}
napi_value ret_value;
status = napi_call_function(env, argv[0], funcGetDateInfo, 0, nullptr, &ret_value);
status = napi_call_function(env, argv[index], funcGetDateInfo, 0, nullptr, &ret_value);
if (status != napi_ok) {
HiLog::Error(LABEL, "Get minute function failed");
return -1;
@ -549,16 +600,16 @@ int64_t IntlAddon::GetMinute(napi_env env, napi_value *argv)
return minute;
}
int64_t IntlAddon::GetSecond(napi_env env, napi_value *argv)
int64_t IntlAddon::GetSecond(napi_env env, napi_value *argv, int index)
{
napi_value funcGetDateInfo;
napi_status status = napi_get_named_property(env, argv[0], "getSeconds", &funcGetDateInfo);
napi_status status = napi_get_named_property(env, argv[index], "getSeconds", &funcGetDateInfo);
if (status != napi_ok) {
HiLog::Error(LABEL, "Get second property failed");
return -1;
}
napi_value ret_value;
status = napi_call_function(env, argv[0], funcGetDateInfo, 0, nullptr, &ret_value);
status = napi_call_function(env, argv[index], funcGetDateInfo, 0, nullptr, &ret_value);
if (status != napi_ok) {
HiLog::Error(LABEL, "Get second function failed");
return -1;
@ -875,6 +926,9 @@ napi_value IntlAddon::GetDateTimeResolvedOptions(napi_env env, napi_callback_inf
SetOptionProperties(env, result, options, "hour");
SetOptionProperties(env, result, options, "minute");
SetOptionProperties(env, result, options, "second");
SetOptionProperties(env, result, options, "dayPeriod");
SetOptionProperties(env, result, options, "localeMatcher");
SetOptionProperties(env, result, options, "formatMatcher");
return result;
}
@ -894,12 +948,22 @@ napi_value IntlAddon::GetNumberResolvedOptions(napi_env env, napi_callback_info
std::map<std::string, std::string> options = {};
obj->datefmt_->GetResolvedOptions(options);
SetOptionProperties(env, result, options, "currency");
SetOptionProperties(env, result, options, "currencySign");
SetOptionProperties(env, result, options, "currencyDisplay");
SetOptionProperties(env, result, options, "unit");
SetOptionProperties(env, result, options, "unitDisplay");
SetOptionProperties(env, result, options, "signDisplay");
SetOptionProperties(env, result, options, "compactDisplay");
SetOptionProperties(env, result, options, "notation");
SetOptionProperties(env, result, options, "style");
SetOptionProperties(env, result, options, "numberingSystem");
SetBooleanOptionProperties(env, result, options, "useGrouping");
SetOptionProperties(env, result, options, "minimumIntegerDigits");
SetOptionProperties(env, result, options, "minimumFractionDigits");
SetOptionProperties(env, result, options, "maximumFractionDigits");
SetOptionProperties(env, result, options, "minimumSignificantDigits");
SetOptionProperties(env, result, options, "maximumSignificantDigits");
SetOptionProperties(env, result, options, "localeMatcher");
return result;
}