14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#include "ecmascript/intl/global_intl_helper.h" 174514f5e3Sopenharmony_ci 184514f5e3Sopenharmony_ci#include "ecmascript/intl/locale_helper.h" 194514f5e3Sopenharmony_ci#include "ecmascript/ecma_macros.h" 204514f5e3Sopenharmony_ci#include "ecmascript/ecma_vm.h" 214514f5e3Sopenharmony_ci#include "ecmascript/global_env.h" 224514f5e3Sopenharmony_ci#include "ecmascript/object_factory.h" 234514f5e3Sopenharmony_ci#include "ecmascript/js_object.h" 244514f5e3Sopenharmony_ci#include "ecmascript/mem/c_string.h" 254514f5e3Sopenharmony_ci 264514f5e3Sopenharmony_cinamespace panda::ecmascript::intl { 274514f5e3Sopenharmony_ciGlobalIntlHelper::GlobalIntlHelper(JSThread *thread, 284514f5e3Sopenharmony_ci const GlobalFormatterType matterType) 294514f5e3Sopenharmony_ci{ 304514f5e3Sopenharmony_ci const GlobalEnvConstants *globalConst = thread->GlobalConstants(); 314514f5e3Sopenharmony_ci auto iter = optionMaps.find(matterType); 324514f5e3Sopenharmony_ci if (iter == optionMaps.end()) { 334514f5e3Sopenharmony_ci switch (matterType) { 344514f5e3Sopenharmony_ci case GlobalFormatterType::Collator: 354514f5e3Sopenharmony_ci InitCollatorData(globalConst); 364514f5e3Sopenharmony_ci break; 374514f5e3Sopenharmony_ci case GlobalFormatterType::SimpleDateFormatDate: 384514f5e3Sopenharmony_ci case GlobalFormatterType::SimpleDateFormatTime: 394514f5e3Sopenharmony_ci case GlobalFormatterType::DateFormatter: 404514f5e3Sopenharmony_ci InitDateData(globalConst); 414514f5e3Sopenharmony_ci break; 424514f5e3Sopenharmony_ci case GlobalFormatterType::NumberFormatter: 434514f5e3Sopenharmony_ci InitNumberData(globalConst); 444514f5e3Sopenharmony_ci break; 454514f5e3Sopenharmony_ci } 464514f5e3Sopenharmony_ci } 474514f5e3Sopenharmony_ci} 484514f5e3Sopenharmony_ci 494514f5e3Sopenharmony_ciuint64_t *GlobalIntlHelper::ConvertDateToUnit(uint64_t timestamp) 504514f5e3Sopenharmony_ci{ 514514f5e3Sopenharmony_ci const uint64_t baseYear = 1900; 524514f5e3Sopenharmony_ci const uint64_t baseTimeSec = 60; 534514f5e3Sopenharmony_ci const uint64_t baseTimeUTC = 8; 544514f5e3Sopenharmony_ci const uint64_t baseTime = 1000; 554514f5e3Sopenharmony_ci auto milli = timestamp + static_cast<uint64_t>(baseTimeUTC * 564514f5e3Sopenharmony_ci baseTimeSec * baseTimeSec * baseTime); 574514f5e3Sopenharmony_ci auto mTime = std::chrono::milliseconds(milli); 584514f5e3Sopenharmony_ci auto tp = std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>(mTime); 594514f5e3Sopenharmony_ci auto tt = std::chrono::system_clock::to_time_t(tp); 604514f5e3Sopenharmony_ci std::tm *now = std::gmtime(&tt); 614514f5e3Sopenharmony_ci dateUnitArr = new uint64_t[6] { 624514f5e3Sopenharmony_ci static_cast<uint64_t>(now->tm_year + baseYear), 634514f5e3Sopenharmony_ci static_cast<uint64_t>(now->tm_mon + 1), 644514f5e3Sopenharmony_ci static_cast<uint64_t>(now->tm_mday), 654514f5e3Sopenharmony_ci static_cast<uint64_t>(now->tm_hour), 664514f5e3Sopenharmony_ci static_cast<uint64_t>(now->tm_min), 674514f5e3Sopenharmony_ci static_cast<uint64_t>(now->tm_sec) 684514f5e3Sopenharmony_ci }; 694514f5e3Sopenharmony_ci return dateUnitArr; 704514f5e3Sopenharmony_ci} 714514f5e3Sopenharmony_ci 724514f5e3Sopenharmony_civoid GlobalIntlHelper::InitCollatorData(const GlobalEnvConstants *globalConst) 734514f5e3Sopenharmony_ci{ 744514f5e3Sopenharmony_ci std::map<std::string, JSHandle<JSTaggedValue>> collatorMap; 754514f5e3Sopenharmony_ci collatorMap["localeMatcher"] = globalConst->GetHandledLocaleMatcherString(); 764514f5e3Sopenharmony_ci collatorMap["usage"] = globalConst->GetHandledUsageString(); 774514f5e3Sopenharmony_ci collatorMap["sensitivity"] = globalConst->GetHandledSensitivityString(); 784514f5e3Sopenharmony_ci collatorMap["ignorePunctuation"] = globalConst->GetHandledIgnorePunctuationString(); 794514f5e3Sopenharmony_ci collatorMap["numeric"] = globalConst->GetHandledNumericString(); 804514f5e3Sopenharmony_ci collatorMap["caseFirst"] = globalConst->GetHandledCaseFirstString(); 814514f5e3Sopenharmony_ci collatorMap["collation"] = globalConst->GetHandledCollationString(); 824514f5e3Sopenharmony_ci optionMaps.insert(make_pair(GlobalFormatterType::Collator, collatorMap)); 834514f5e3Sopenharmony_ci} 844514f5e3Sopenharmony_ci 854514f5e3Sopenharmony_civoid GlobalIntlHelper::InitDateData(const GlobalEnvConstants *globalConst) 864514f5e3Sopenharmony_ci{ 874514f5e3Sopenharmony_ci std::map<std::string, JSHandle<JSTaggedValue>> collatorMap; 884514f5e3Sopenharmony_ci collatorMap["dateStyle"] = globalConst->GetHandledDateStyleString(); 894514f5e3Sopenharmony_ci collatorMap["timeStyle"] = globalConst->GetHandledTimeStyleString(); 904514f5e3Sopenharmony_ci collatorMap["calendar"] = globalConst->GetHandledCalendarString(); 914514f5e3Sopenharmony_ci collatorMap["numberingSystem"] = globalConst->GetHandledNumberingSystemString(); 924514f5e3Sopenharmony_ci collatorMap["localeMatcher"] = globalConst->GetHandledLocaleMatcherString(); 934514f5e3Sopenharmony_ci collatorMap["timeZone"] = globalConst->GetHandledTimeZoneString(); 944514f5e3Sopenharmony_ci collatorMap["hour12"] = globalConst->GetHandledHour12String(); 954514f5e3Sopenharmony_ci collatorMap["hourCycle"] = globalConst->GetHandledHourCycleString(); 964514f5e3Sopenharmony_ci collatorMap["formatMatcher"] = globalConst->GetHandledFormatMatcherString(); 974514f5e3Sopenharmony_ci collatorMap["weekday"] = globalConst->GetHandledWeekdayString(); 984514f5e3Sopenharmony_ci collatorMap["era"] = globalConst->GetHandledEraString(); 994514f5e3Sopenharmony_ci collatorMap["year"] = globalConst->GetHandledYearString(); 1004514f5e3Sopenharmony_ci collatorMap["month"] = globalConst->GetHandledMonthString(); 1014514f5e3Sopenharmony_ci collatorMap["day"] = globalConst->GetHandledDayString(); 1024514f5e3Sopenharmony_ci collatorMap["hour"] = globalConst->GetHandledHourString(); 1034514f5e3Sopenharmony_ci collatorMap["minute"] = globalConst->GetHandledMinuteString(); 1044514f5e3Sopenharmony_ci collatorMap["second"] = globalConst->GetHandledSecondString(); 1054514f5e3Sopenharmony_ci collatorMap["fractionalSecondDigits"] = globalConst->GetHandledFractionalSecondDigitsString(); 1064514f5e3Sopenharmony_ci collatorMap["timeZoneName"] = globalConst->GetHandledTimeZoneNameString(); 1074514f5e3Sopenharmony_ci optionMaps.insert(make_pair(GlobalFormatterType::DateFormatter, collatorMap)); 1084514f5e3Sopenharmony_ci} 1094514f5e3Sopenharmony_ci 1104514f5e3Sopenharmony_civoid GlobalIntlHelper::InitNumberData(const GlobalEnvConstants *globalConst) 1114514f5e3Sopenharmony_ci{ 1124514f5e3Sopenharmony_ci std::map<std::string, JSHandle<JSTaggedValue>> collatorMap; 1134514f5e3Sopenharmony_ci collatorMap["localeMatcher"] = globalConst->GetHandledLocaleMatcherString(); 1144514f5e3Sopenharmony_ci collatorMap["numberingSystem"] = globalConst->GetHandledNumberingSystemString(); 1154514f5e3Sopenharmony_ci collatorMap["notation"] = globalConst->GetHandledNotationString(); 1164514f5e3Sopenharmony_ci collatorMap["compactDisplay"] = globalConst->GetHandledCompactDisplayString(); 1174514f5e3Sopenharmony_ci collatorMap["useGrouping"] = globalConst->GetHandledUserGroupingString(); 1184514f5e3Sopenharmony_ci collatorMap["signDisplay"] = globalConst->GetHandledSignDisplayString(); 1194514f5e3Sopenharmony_ci collatorMap["style"] = globalConst->GetHandledStyleString(); 1204514f5e3Sopenharmony_ci collatorMap["currency"] = globalConst->GetHandledCurrencyString(); 1214514f5e3Sopenharmony_ci collatorMap["currencySign"] = globalConst->GetHandledCurrencySignString(); 1224514f5e3Sopenharmony_ci collatorMap["currencyDisplay"] = globalConst->GetHandledCurrencyDisplayString(); 1234514f5e3Sopenharmony_ci collatorMap["unit"] = globalConst->GetHandledUnitString(); 1244514f5e3Sopenharmony_ci collatorMap["unitDisplay"] = globalConst->GetHandledUnitDisplayString(); 1254514f5e3Sopenharmony_ci collatorMap["minimumIntegerDigits"] = globalConst->GetHandledMinimumIntegerDigitsString(); 1264514f5e3Sopenharmony_ci collatorMap["minimumFractionDigits"] = globalConst->GetHandledMinimumFractionDigitsString(); 1274514f5e3Sopenharmony_ci collatorMap["maximumFractionDigits"] = globalConst->GetHandledMaximumFractionDigitsString(); 1284514f5e3Sopenharmony_ci collatorMap["minimumSignificantDigits"] = globalConst->GetHandledMinimumSignificantDigitsString(); 1294514f5e3Sopenharmony_ci collatorMap["maximumSignificantDigits"] = globalConst->GetHandledMaximumSignificantDigitsString(); 1304514f5e3Sopenharmony_ci optionMaps.insert(make_pair(GlobalFormatterType::NumberFormatter, collatorMap)); 1314514f5e3Sopenharmony_ci} 1324514f5e3Sopenharmony_ci 1334514f5e3Sopenharmony_cistd::map<std::string, std::string> GlobalIntlHelper::OptionsToMap(JSThread *thread, 1344514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &options, GlobalFormatterType types) 1354514f5e3Sopenharmony_ci{ 1364514f5e3Sopenharmony_ci std::map<std::string, std::string> inputOptions; 1374514f5e3Sopenharmony_ci JSHandle<JSObject> optionsObject; 1384514f5e3Sopenharmony_ci if (options->IsUndefined()) { 1394514f5e3Sopenharmony_ci return inputOptions; 1404514f5e3Sopenharmony_ci } else { 1414514f5e3Sopenharmony_ci optionsObject = JSTaggedValue::ToObject(thread, options); 1424514f5e3Sopenharmony_ci } 1434514f5e3Sopenharmony_ci if (optionMaps.size() == 0) { 1444514f5e3Sopenharmony_ci LOG_ECMA(ERROR) << "GlobalIntlHelper::OptionsToMap size is zero"; 1454514f5e3Sopenharmony_ci return inputOptions; 1464514f5e3Sopenharmony_ci } 1474514f5e3Sopenharmony_ci 1484514f5e3Sopenharmony_ci auto matterType = types; 1494514f5e3Sopenharmony_ci if (types == GlobalFormatterType::SimpleDateFormatDate || 1504514f5e3Sopenharmony_ci types == GlobalFormatterType::SimpleDateFormatTime) { 1514514f5e3Sopenharmony_ci matterType = GlobalFormatterType::DateFormatter; 1524514f5e3Sopenharmony_ci } 1534514f5e3Sopenharmony_ci 1544514f5e3Sopenharmony_ci auto iter = optionMaps.find(matterType); 1554514f5e3Sopenharmony_ci if (iter != optionMaps.end()) { 1564514f5e3Sopenharmony_ci for (auto &opt : optionMaps[matterType]) { 1574514f5e3Sopenharmony_ci OperationResult operationResult = JSObject::GetProperty(thread, optionsObject, opt.second); 1584514f5e3Sopenharmony_ci if (!operationResult.GetValue()->IsUndefined()) { 1594514f5e3Sopenharmony_ci std::string valueStr = std::string(EcmaConvertToStr(JSTaggedValue::ToString(thread, 1604514f5e3Sopenharmony_ci operationResult.GetValue()))); 1614514f5e3Sopenharmony_ci auto inOpt = inputOptions.find(opt.first); 1624514f5e3Sopenharmony_ci if (inOpt != inputOptions.end()) { 1634514f5e3Sopenharmony_ci inputOptions[opt.first] = valueStr; 1644514f5e3Sopenharmony_ci } else { 1654514f5e3Sopenharmony_ci inputOptions.insert(make_pair(opt.first, valueStr)); 1664514f5e3Sopenharmony_ci } 1674514f5e3Sopenharmony_ci } 1684514f5e3Sopenharmony_ci } 1694514f5e3Sopenharmony_ci } 1704514f5e3Sopenharmony_ci return OptionsWithDataFormatter(inputOptions, types); 1714514f5e3Sopenharmony_ci} 1724514f5e3Sopenharmony_ci 1734514f5e3Sopenharmony_cistd::map<std::string, std::string> GlobalIntlHelper::OptionsWithDataFormatter(std::map<std::string, 1744514f5e3Sopenharmony_ci std::string> &options, GlobalFormatterType &types) 1754514f5e3Sopenharmony_ci{ 1764514f5e3Sopenharmony_ci std::vector<std::string> all; 1774514f5e3Sopenharmony_ci if (types == GlobalFormatterType::DateFormatter) { 1784514f5e3Sopenharmony_ci all = {"year", "month", "day", "hour", "minute", "second"}; 1794514f5e3Sopenharmony_ci } 1804514f5e3Sopenharmony_ci if (types == GlobalFormatterType::SimpleDateFormatDate) { 1814514f5e3Sopenharmony_ci all = {"year", "month", "day"}; 1824514f5e3Sopenharmony_ci } 1834514f5e3Sopenharmony_ci if (types == GlobalFormatterType::SimpleDateFormatTime) { 1844514f5e3Sopenharmony_ci all = {"hour", "minute", "second"}; 1854514f5e3Sopenharmony_ci } 1864514f5e3Sopenharmony_ci for (auto &item : all) { 1874514f5e3Sopenharmony_ci auto iter = options.find(item); 1884514f5e3Sopenharmony_ci if (iter == options.end()) { 1894514f5e3Sopenharmony_ci options[item] = "numeric"; 1904514f5e3Sopenharmony_ci } 1914514f5e3Sopenharmony_ci } 1924514f5e3Sopenharmony_ci return options; 1934514f5e3Sopenharmony_ci} 1944514f5e3Sopenharmony_ci 1954514f5e3Sopenharmony_ciint64_t GlobalIntlHelper::DoubleToInt64(double value) 1964514f5e3Sopenharmony_ci{ 1974514f5e3Sopenharmony_ci return static_cast<int64_t>(round(value)); 1984514f5e3Sopenharmony_ci} 1994514f5e3Sopenharmony_ci 2004514f5e3Sopenharmony_cistd::string GlobalIntlHelper::EcmaConvertToStr(const JSHandle<EcmaString> &string) 2014514f5e3Sopenharmony_ci{ 2024514f5e3Sopenharmony_ci return std::string(ConvertToString(*string, StringConvertedUsage::LOGICOPERATION)); 2034514f5e3Sopenharmony_ci} 2044514f5e3Sopenharmony_ci 2054514f5e3Sopenharmony_cistd::vector<std::string> GlobalIntlHelper::LocalesToVector(JSThread *thread, 2064514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &locales) 2074514f5e3Sopenharmony_ci{ 2084514f5e3Sopenharmony_ci JSHandle<TaggedArray> tArray = intl::LocaleHelper::CanonicalizeLocaleList(thread, locales); 2094514f5e3Sopenharmony_ci return TaggedArrayToVector(thread, tArray); 2104514f5e3Sopenharmony_ci} 2114514f5e3Sopenharmony_ci 2124514f5e3Sopenharmony_cistd::vector<std::string> GlobalIntlHelper::TaggedArrayToVector(JSThread *thread, 2134514f5e3Sopenharmony_ci JSHandle<TaggedArray> &taggedarray) 2144514f5e3Sopenharmony_ci{ 2154514f5e3Sopenharmony_ci std::vector<std::string> availableStringLocales; 2164514f5e3Sopenharmony_ci JSMutableHandle<EcmaString> availableItem(thread, JSTaggedValue::Undefined()); 2174514f5e3Sopenharmony_ci uint32_t availablecalesLength = taggedarray->GetLength(); 2184514f5e3Sopenharmony_ci for (uint32_t i = 0; i < availablecalesLength; i++) { 2194514f5e3Sopenharmony_ci availableItem.Update(taggedarray->Get(thread, i)); 2204514f5e3Sopenharmony_ci availableStringLocales.emplace_back(intl::LocaleHelper::ConvertToStdString(availableItem)); 2214514f5e3Sopenharmony_ci } 2224514f5e3Sopenharmony_ci return availableStringLocales; 2234514f5e3Sopenharmony_ci} 2244514f5e3Sopenharmony_ci} // panda::ecmascript::base 225