From fceee88972bdcfd4a012566633fbb85237c41a16 Mon Sep 17 00:00:00 2001 From: sunyaozu Date: Sat, 25 Jun 2022 11:35:24 +0800 Subject: [PATCH] add interface of timezone Signed-off-by: sunyaozu --- frameworks/intl/BUILD.gn | 25 +++ frameworks/intl/etc/timezone/en-Latn.xml | 136 ++++++++++++ .../intl/etc/timezone/supported_locales.xml | 18 ++ frameworks/intl/etc/timezone/zh-Hans.xml | 136 ++++++++++++ frameworks/intl/include/i18n_timezone.h | 27 ++- frameworks/intl/include/locale_info.h | 2 +- frameworks/intl/src/i18n_timezone.cpp | 176 ++++++++++++++- frameworks/intl/src/locale_info.cpp | 3 +- interfaces/js/kits/include/i18n_addon.h | 7 + interfaces/js/kits/src/i18n_addon.cpp | 203 +++++++++++++++--- 10 files changed, 690 insertions(+), 43 deletions(-) create mode 100644 frameworks/intl/etc/timezone/en-Latn.xml create mode 100644 frameworks/intl/etc/timezone/supported_locales.xml create mode 100644 frameworks/intl/etc/timezone/zh-Hans.xml diff --git a/frameworks/intl/BUILD.gn b/frameworks/intl/BUILD.gn index 81704b44..1a4bbf73 100644 --- a/frameworks/intl/BUILD.gn +++ b/frameworks/intl/BUILD.gn @@ -85,10 +85,13 @@ ohos_shared_library("intl_util") { deps = [ ":config_locales_xml", ":config_regions_xml", + ":en_Latn_timezone_xml", ":forbidden_languages_xml", ":forbidden_regions_xml", ":language_config.para", + ":timezone_supported_locales", ":white_languages_xml", + ":zh_Hans_timezone_xml", "//third_party/icu/icu4c:ohos_icudat", "//third_party/icu/icu4c:shared_icui18n", "//third_party/icu/icu4c:shared_icuuc", @@ -151,3 +154,25 @@ ohos_prebuilt_etc("forbidden_regions_xml") { part_name = "i18n" subsystem_name = "global" } + +ohos_prebuilt_etc("zh_Hans_timezone_xml") { + source = "//base/global/i18n/frameworks/intl/etc/timezone/zh-Hans.xml" + module_install_dir = "usr/ohos_timezone/" + part_name = "i18n" + subsystem_name = "global" +} + +ohos_prebuilt_etc("en_Latn_timezone_xml") { + source = "//base/global/i18n/frameworks/intl/etc/timezone/en-Latn.xml" + module_install_dir = "usr/ohos_timezone/" + part_name = "i18n" + subsystem_name = "global" +} + +ohos_prebuilt_etc("timezone_supported_locales") { + source = + "//base/global/i18n/frameworks/intl/etc/timezone/supported_locales.xml" + module_install_dir = "usr/ohos_timezone/" + part_name = "i18n" + subsystem_name = "global" +} diff --git a/frameworks/intl/etc/timezone/en-Latn.xml b/frameworks/intl/etc/timezone/en-Latn.xml new file mode 100644 index 00000000..4d13a590 --- /dev/null +++ b/frameworks/intl/etc/timezone/en-Latn.xml @@ -0,0 +1,136 @@ + + + + + Auckland + Pacific/Auckland + Auckland (New Zealand) + + + Magadan + Asia/Magadan + Magadan (Russia) + + + Lord Howe Island + Australia/Lord_Howe + Lord Howe Island (Australia) + + + Tokyo + Asia/Tokyo + Tokyo (Japan) + + + Shanghai + Asia/Shanghai + Shanghai (China) + + + Hovd + Asia/Hovd + Khovd (Mongolia) + + + Omsk + Asia/Omsk + Omsk (Russia) + + + Ashgabat + Asia/Ashgabat + Ashgabat (Turkmenistan) + + + Yerevan + Asia/Yerevan + Yerevan (Armenia) + + + Moscow + Europe/Moscow + Moscow (Russia) + + + Tel Aviv + Asia/Jerusalem + Tel Aviv (Israel) + + + Dublin + Europe/Dublin + Dublin (Ireland) + + + London + Europe/London + London (United Kingdom) + + + Praia + Atlantic/Cape_Verde + Praia (Cape Verde) + + + Montevideo + America/Montevideo + Montevideo (Uruguay) + + + Brasília + America/Sao_Paulo + Brasília (Brazil) + + + Stanley + Atlantic/Stanley + Stanley (Falkland Islands) + + + Bogotá + America/Bogota + Bogotá (Colombia) + + + Easter Island + Pacific/Easter + Easter Island (Chile) + + + Salt Lake City + America/Denver + Salt Lake City (United States) + + + Los Angeles + America/Los_Angeles + Los Angeles (United States) + + + Anchorage + America/Anchorage + Anchorage (United States) + + + Adak + America/Adak + Adak (United States) + + + Pago Pago + Pacific/Pago-Pago + Pago Pago (American Samoa) + + \ No newline at end of file diff --git a/frameworks/intl/etc/timezone/supported_locales.xml b/frameworks/intl/etc/timezone/supported_locales.xml new file mode 100644 index 00000000..b1165455 --- /dev/null +++ b/frameworks/intl/etc/timezone/supported_locales.xml @@ -0,0 +1,18 @@ + + + + en-Latn + zh-Hans + \ No newline at end of file diff --git a/frameworks/intl/etc/timezone/zh-Hans.xml b/frameworks/intl/etc/timezone/zh-Hans.xml new file mode 100644 index 00000000..a1b37241 --- /dev/null +++ b/frameworks/intl/etc/timezone/zh-Hans.xml @@ -0,0 +1,136 @@ + + + + + Auckland + Pacific/Auckland + 奥克兰 (新西兰) + + + Magadan + Asia/Magadan + 马加丹 (俄罗斯) + + + Lord Howe Island + Australia/Lord_Howe + 豪勋爵岛 (澳大利亚) + + + Tokyo + Asia/Tokyo + 东京 (日本) + + + Shanghai + Asia/Shanghai + 上海 (中国) + + + Hovd + Asia/Hovd + 科布多 (蒙古) + + + Omsk + Asia/Omsk + 鄂木斯克 (俄罗斯) + + + Ashgabat + Asia/Ashgabat + 阿什哈巴德 (土库曼斯坦) + + + Yerevan + Asia/Yerevan + 埃里温 (亚美尼亚) + + + Moscow + Europe/Moscow + 莫斯科 (俄罗斯) + + + Tel Aviv + Asia/Jerusalem + 特拉维夫 (以色列) + + + Dublin + Europe/Dublin + 都柏林 (爱尔兰) + + + London + Europe/London + 伦敦 (英国) + + + Praia + Atlantic/Cape_Verde + 普拉亚 (佛得角) + + + Montevideo + America/Montevideo + 蒙得维的亚 (乌拉圭) + + + Brasília + America/Sao_Paulo + 巴西利亚 (巴西) + + + Stanley + Atlantic/Stanley + 史丹利 (福克兰群岛) + + + Bogotá + America/Bogota + 波哥大 (哥伦比亚) + + + Easter Island + Pacific/Easter + 复活节岛 (智利) + + + Salt Lake City + America/Denver + 盐湖城 (美国) + + + Los Angeles + America/Los_Angeles + 洛杉矶 (美国) + + + Anchorage + America/Anchorage + 安克雷奇 (美国) + + + Adak + America/Adak + 埃达克 (美国) + + + Pago Pago + Pacific/Pago-Pago + 帕果-帕果 (美属萨摩耶) + + \ No newline at end of file diff --git a/frameworks/intl/include/i18n_timezone.h b/frameworks/intl/include/i18n_timezone.h index d1e31ce1..1caa9d5b 100644 --- a/frameworks/intl/include/i18n_timezone.h +++ b/frameworks/intl/include/i18n_timezone.h @@ -15,7 +15,10 @@ #ifndef OHOS_GLOBAL_I18N_TIMEZONE_H #define OHOS_GLOBAL_I18N_TIMEZONE_H +#include +#include #include +#include #include "unicode/timezone.h" namespace OHOS { @@ -23,7 +26,7 @@ namespace Global { namespace I18n { class I18nTimeZone { public: - I18nTimeZone(std::string zoneID); + I18nTimeZone(std::string &id, bool isZoneID); ~I18nTimeZone(); int32_t GetOffset(double date); int32_t GetRawOffset(); @@ -32,9 +35,29 @@ public: std::string GetDisplayName(bool isDST); std::string GetDisplayName(std::string localeStr); std::string GetDisplayName(std::string localeStr, bool isDST); - static std::unique_ptr CreateInstance(std::string zoneID); + static std::unique_ptr CreateInstance(std::string &id, bool isZoneID); + static std::set GetAvailableIDs(); + static std::vector GetAvailableZoneCityIDs(); + static std::string GetCityDisplayName(std::string &cityID, std::string &locale); private: + static const char *DEFAULT_LANGUAGE; + static const char *DEFAULT_LOCALE; + static const char *TIMEZONES_PATH; + static const char *SUPPORT_LOCALES_PATH; + static const char *rootTag; + static const char *secondRootTag; + static const uint32_t ELEMENT_NUM = 3; + static const char *supportLocalesTag; + static std::string displayLocale; + static bool isInitialized; + static std::set availableIDs; + static std::vector availableZoneCityIDs; + static std::map city2DisplayName; + static std::map city2TimeZoneID; + static std::map supportLocales; + static void ReadTimeZoneData(const char *xmlPath); + static std::string ComputeLocale(std::string &locale); icu::TimeZone* GetTimeZone(); icu::TimeZone *timezone; }; diff --git a/frameworks/intl/include/locale_info.h b/frameworks/intl/include/locale_info.h index 29f384bb..1b2f268b 100644 --- a/frameworks/intl/include/locale_info.h +++ b/frameworks/intl/include/locale_info.h @@ -26,7 +26,7 @@ namespace Global { namespace I18n { class LocaleInfo { public: - explicit LocaleInfo(std::string locale); + explicit LocaleInfo(const std::string &locale); LocaleInfo(const std::string &localeTag, std::map &configs); virtual ~LocaleInfo(); std::string GetLanguage() const; diff --git a/frameworks/intl/src/i18n_timezone.cpp b/frameworks/intl/src/i18n_timezone.cpp index 5bb50a35..5682080c 100644 --- a/frameworks/intl/src/i18n_timezone.cpp +++ b/frameworks/intl/src/i18n_timezone.cpp @@ -13,7 +13,9 @@ * limitations under the License. */ +#include "libxml/parser.h" #include "locale_config.h" +#include "locale_info.h" #include "unicode/locid.h" #include "unicode/unistr.h" #include "i18n_timezone.h" @@ -21,13 +23,43 @@ namespace OHOS { namespace Global { namespace I18n { -I18nTimeZone::I18nTimeZone(std::string zoneID) +const char *I18nTimeZone::DEFAULT_LANGUAGE = "/system/usr/ohos_timezone/en-Latn.xml"; +const char *I18nTimeZone::DEFAULT_LOCALE = "en-Latn"; +const char *I18nTimeZone::TIMEZONES_PATH = "/system/usr/ohos_timezone/"; +const char *I18nTimeZone::SUPPORT_LOCALES_PATH = "/system/usr/ohos_timezone/supported_locales.xml"; +const char *I18nTimeZone::rootTag = "timezones"; +const char *I18nTimeZone::secondRootTag = "timezone"; +const char *I18nTimeZone::supportLocalesTag = "supported_locales"; +std::string I18nTimeZone::displayLocale = ""; +bool I18nTimeZone::isInitialized = false; + +std::map I18nTimeZone::supportLocales {}; +std::set I18nTimeZone::availableIDs {}; +std::vector I18nTimeZone::availableZoneCityIDs {}; +std::map I18nTimeZone::city2DisplayName {}; +std::map I18nTimeZone::city2TimeZoneID {}; + +I18nTimeZone::I18nTimeZone(std::string &id, bool isZoneID) { - if (zoneID.empty()) { - timezone = icu::TimeZone::createDefault(); + if (isZoneID) { + if (id.empty()) { + timezone = icu::TimeZone::createDefault(); + } else { + icu::UnicodeString unicodeZoneID(id.data(), id.length()); + timezone = icu::TimeZone::createTimeZone(unicodeZoneID); + } } else { - icu::UnicodeString unicodeZoneID(zoneID.data(), zoneID.length()); - timezone = icu::TimeZone::createTimeZone(unicodeZoneID); + if (!isInitialized) { + ReadTimeZoneData(DEFAULT_LANGUAGE); + isInitialized = true; + } + if (city2TimeZoneID.find(id) == city2TimeZoneID.end()) { + timezone = icu::TimeZone::createDefault(); + } else { + std::string timezoneID = city2TimeZoneID.at(id); + icu::UnicodeString unicodeZoneID(timezoneID.data(), timezoneID.length()); + timezone = icu::TimeZone::createTimeZone(unicodeZoneID); + } } } @@ -44,9 +76,9 @@ icu::TimeZone* I18nTimeZone::GetTimeZone() return timezone; } -std::unique_ptr I18nTimeZone::CreateInstance(std::string zoneID) +std::unique_ptr I18nTimeZone::CreateInstance(std::string &id, bool isZoneID) { - std::unique_ptr i18nTimeZone = std::make_unique(zoneID); + std::unique_ptr i18nTimeZone = std::make_unique(id, isZoneID); if (i18nTimeZone->GetTimeZone() == nullptr) { return nullptr; } @@ -107,6 +139,134 @@ std::string I18nTimeZone::GetDisplayName(std::string localeStr, bool isDST) name.toUTF8String(result); return result; } + +void I18nTimeZone::ReadTimeZoneData(const char *xmlPath) +{ + xmlKeepBlanksDefault(0); + if (xmlPath == nullptr) { + return; + } + xmlDocPtr doc = xmlParseFile(xmlPath); + if (!doc) { + return; + } + xmlNodePtr cur = xmlDocGetRootElement(doc); + if (!cur || xmlStrcmp(cur->name, reinterpret_cast(rootTag))) { + xmlFreeDoc(doc); + return; + } + cur = cur->xmlChildrenNode; + while (cur != nullptr && !xmlStrcmp(cur->name, reinterpret_cast(secondRootTag))) { + xmlNodePtr value = cur->xmlChildrenNode; + xmlChar *contents[ELEMENT_NUM] = { 0 }; // 3 represent cityid, zoneid, displayname; + for (size_t i = 0; i < ELEMENT_NUM; i++) { + if (value != nullptr) { + contents[i] = xmlNodeGetContent(value); + value = value->next; + } else { + break; + } + } + if (!isInitialized) { + // 0 represents cityid index, 1 represents zoneid index + availableZoneCityIDs.insert(availableZoneCityIDs.end(), reinterpret_cast(contents[0])); + availableIDs.insert(reinterpret_cast(contents[1])); + city2TimeZoneID.insert( + std::make_pair(reinterpret_cast(contents[0]), + reinterpret_cast(contents[1]))); + } + // 0 represents cityid index, 2 represents displayname index + city2DisplayName.insert( + std::make_pair(reinterpret_cast(contents[0]), + reinterpret_cast(contents[2]))); + for (size_t i = 0; i < ELEMENT_NUM; i++) { + if (contents[i] != nullptr) { + xmlFree(contents[i]); + } + } + cur = cur->next; + } + xmlFreeDoc(doc); +} + +std::set I18nTimeZone::GetAvailableIDs() +{ + if (!isInitialized) { + ReadTimeZoneData(DEFAULT_LANGUAGE); + isInitialized = true; + } + return availableIDs; +} + +std::vector I18nTimeZone::GetAvailableZoneCityIDs() +{ + if (!isInitialized) { + ReadTimeZoneData(DEFAULT_LANGUAGE); + isInitialized = true; + } + return availableZoneCityIDs; +} + +std::string I18nTimeZone::ComputeLocale(std::string &locale) +{ + if (supportLocales.size() == 0) { + xmlKeepBlanksDefault(0); + xmlDocPtr doc = xmlParseFile(SUPPORT_LOCALES_PATH); + if (!doc) { + return DEFAULT_LOCALE; + } + xmlNodePtr cur = xmlDocGetRootElement(doc); + if (!cur || xmlStrcmp(cur->name, reinterpret_cast(supportLocalesTag))) { + xmlFreeDoc(doc); + return DEFAULT_LOCALE; + } + cur = cur->xmlChildrenNode; + while (cur != nullptr) { + xmlChar *content = xmlNodeGetContent(cur); + if (content == nullptr) { + break; + } + std::map configs = {}; + LocaleInfo localeinfo(reinterpret_cast(content), configs); + std::string language = localeinfo.GetLanguage(); + std::string script = localeinfo.GetScript(); + std::string languageAndScript = (script.length() == 0) ? language : language + "-" + script; + LocaleInfo newLocaleInfo(languageAndScript, configs); + std::string maximizeLocale = newLocaleInfo.Maximize(); + supportLocales.insert( + std::make_pair(maximizeLocale.c_str(), + reinterpret_cast(content))); + xmlFree(content); + cur = cur->next; + } + } + std::map configs = {}; + LocaleInfo localeinfo(locale, configs); + std::string language = localeinfo.GetLanguage(); + std::string script = localeinfo.GetScript(); + std::string languageAndScript = (script.length() == 0) ? language : language + "-" + script; + LocaleInfo newLocaleInfo(languageAndScript, configs); + std::string maximizeLocale = newLocaleInfo.Maximize(); + if (supportLocales.find(maximizeLocale) != supportLocales.end()) { + return supportLocales.at(maximizeLocale); + } + return DEFAULT_LOCALE; +} + +std::string I18nTimeZone::GetCityDisplayName(std::string &cityID, std::string &locale) +{ + std::string finalLocale = ComputeLocale(locale); + if (finalLocale.compare(displayLocale) != 0) { + std::string xmlPath = TIMEZONES_PATH + finalLocale + ".xml"; + city2DisplayName.clear(); + ReadTimeZoneData(xmlPath.c_str()); + displayLocale = finalLocale; + } + if (city2DisplayName.find(cityID) == city2DisplayName.end()) { + return ""; + } + return city2DisplayName.at(cityID); +} +} } } -} \ No newline at end of file diff --git a/frameworks/intl/src/locale_info.cpp b/frameworks/intl/src/locale_info.cpp index ab1271fc..18e3b902 100644 --- a/frameworks/intl/src/locale_info.cpp +++ b/frameworks/intl/src/locale_info.cpp @@ -20,7 +20,6 @@ namespace OHOS { namespace Global { namespace I18n { using namespace icu; - std::set LocaleInfo::allValidLocales = GetValidLocales(); std::set LocaleInfo::GetValidLocales() @@ -37,7 +36,7 @@ std::set LocaleInfo::GetValidLocales() return allValidLocales; } -LocaleInfo::LocaleInfo(std::string localeTag) +LocaleInfo::LocaleInfo(const std::string &localeTag) { UErrorCode status = U_ZERO_ERROR; configs = {}; diff --git a/interfaces/js/kits/include/i18n_addon.h b/interfaces/js/kits/include/i18n_addon.h index a342b5d0..d556052a 100644 --- a/interfaces/js/kits/include/i18n_addon.h +++ b/interfaces/js/kits/include/i18n_addon.h @@ -82,6 +82,10 @@ public: static napi_value GetAvailableIDs(napi_env env, napi_callback_info info); static napi_value SetUsingLocalDigitAddon(napi_env env, napi_callback_info info); static napi_value GetUsingLocalDigitAddon(napi_env env, napi_callback_info info); + static napi_value GetAvailableTimezoneIDs(napi_env env, napi_callback_info info); + static napi_value GetAvailableZoneCityIDs(napi_env env, napi_callback_info info); + static napi_value GetCityDisplayName(napi_env env, napi_callback_info info); + static napi_value GetTimezoneFromCity(napi_env env, napi_callback_info info); private: static void CreateInitProperties(napi_property_descriptor *properties); @@ -146,6 +150,9 @@ private: static void ProcessNormal(char ch, int *order, size_t orderSize, int *lengths, size_t lengsSize); static bool GetStringFromJS(napi_env env, napi_value argv, std::string &jsString); + static napi_value StaticGetTimeZone(napi_env, napi_value *argv, bool isZoneID); + static napi_value CreateTimeZoneObject(napi_env env); + napi_env env_; napi_ref wrapper_; std::unique_ptr phonenumberfmt_ = nullptr; diff --git a/interfaces/js/kits/src/i18n_addon.cpp b/interfaces/js/kits/src/i18n_addon.cpp index e7a19fb2..ffbaa2d2 100644 --- a/interfaces/js/kits/src/i18n_addon.cpp +++ b/interfaces/js/kits/src/i18n_addon.cpp @@ -184,12 +184,17 @@ napi_value I18nAddon::Init(napi_env env, napi_value exports) if (!transliterator) { return nullptr; } - size_t propertiesNums = 27; + napi_value timezone = CreateTimeZoneObject(env); + if (!timezone) { + return nullptr; + } + size_t propertiesNums = 28; napi_property_descriptor properties[propertiesNums]; CreateInitProperties(properties); properties[13] = DECLARE_NAPI_PROPERTY("Util", util); // 13 is properties index properties[16] = DECLARE_NAPI_PROPERTY("Character", character); // 16 is properties index properties[24] = DECLARE_NAPI_PROPERTY("Transliterator", transliterator); // 24 is properties index + properties[27] = DECLARE_NAPI_PROPERTY("TimeZone", timezone); // 27 is properties index status = napi_define_properties(env, exports, propertiesNums, properties); if (status != napi_ok) { HiLog::Error(LABEL, "Failed to set properties at init"); @@ -2833,8 +2838,8 @@ napi_value I18nAddon::InitI18nTimeZone(napi_env env, napi_value exports) napi_value I18nAddon::I18nTimeZoneConstructor(napi_env env, napi_callback_info info) { - size_t argc = 1; - napi_value argv[1] = { nullptr }; + size_t argc = 2; + napi_value argv[2] = { nullptr }; napi_value thisVar = nullptr; void *data = nullptr; napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); @@ -2842,11 +2847,10 @@ napi_value I18nAddon::I18nTimeZoneConstructor(napi_env env, napi_callback_info i return nullptr; } std::string zoneID = ""; + napi_valuetype valueType = napi_valuetype::napi_undefined; if (argv[0] != nullptr) { - napi_valuetype valueType = napi_valuetype::napi_undefined; napi_typeof(env, argv[0], &valueType); if (valueType != napi_valuetype::napi_string) { - napi_throw_type_error(env, nullptr, "Parameter type does not match"); return nullptr; } int32_t code = 0; @@ -2855,21 +2859,29 @@ napi_value I18nAddon::I18nTimeZoneConstructor(napi_env env, napi_callback_info i return nullptr; } } - std::unique_ptr obj = nullptr; - obj = std::make_unique(); + if (argv[1] == nullptr) { + return nullptr; + } + napi_typeof(env, argv[1], &valueType); + if (valueType != napi_valuetype::napi_boolean) { + return nullptr; + } + bool isZoneID = false; + status = napi_get_value_bool(env, argv[1], &isZoneID); + if (status != napi_ok) { + return nullptr; + } + std::unique_ptr obj = std::make_unique(); if (!obj) { - HiLog::Error(LABEL, "Create I18nAddon failed"); return nullptr; } status = napi_wrap(env, thisVar, reinterpret_cast(obj.get()), I18nAddon::Destructor, nullptr, &obj->wrapper_); if (status != napi_ok) { - HiLog::Error(LABEL, "Wrap II18nAddon failed"); return nullptr; } - obj->timezone_ = I18nTimeZone::CreateInstance(zoneID); + obj->timezone_ = I18nTimeZone::CreateInstance(zoneID, isZoneID); if (!obj->timezone_) { - HiLog::Error(LABEL, "Wrap TimeZone failed"); return nullptr; } obj.release(); @@ -2883,24 +2895,8 @@ napi_value I18nAddon::GetI18nTimeZone(napi_env env, napi_callback_info info) napi_value thisVar = nullptr; void *data = nullptr; napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); - napi_value constructor = nullptr; - napi_status status = napi_get_reference_value(env, *g_timezoneConstructor, &constructor); - if (status != napi_ok) { - HiLog::Error(LABEL, "Failed to create reference at GetTimeZoneInstance"); - return nullptr; - } - - napi_value result = nullptr; - if (!argv[0]) { - status = napi_new_instance(env, constructor, 0, nullptr, &result); // 1 arguments - } else { - status = napi_new_instance(env, constructor, 1, argv, &result); // 1 arguments - } - if (status != napi_ok) { - HiLog::Error(LABEL, "GetTimeZone create instance failed"); - return nullptr; - } - return result; + + return StaticGetTimeZone(env, argv, true); } napi_value I18nAddon::GetID(napi_env env, napi_callback_info info) @@ -3126,7 +3122,7 @@ napi_value I18nAddon::SetUsingLocalDigitAddon(napi_env env, napi_callback_info i HiLog::Error(LABEL, "Get parameter flag failed"); return nullptr; } - + bool res = LocaleConfig::SetUsingLocalDigit(flag); napi_value value = nullptr; status = napi_get_boolean(env, res, &value); @@ -3148,6 +3144,153 @@ napi_value I18nAddon::GetUsingLocalDigitAddon(napi_env env, napi_callback_info i return value; } +napi_value I18nAddon::CreateTimeZoneObject(napi_env env) +{ + napi_status status = napi_ok; + napi_value timezone = nullptr; + status = napi_create_object(env, &timezone); + if (status != napi_ok) { + HiLog::Error(LABEL, "Failed to create timezone object at init"); + return nullptr; + } + napi_property_descriptor timezoneProperties[] = { + DECLARE_NAPI_FUNCTION("getAvailableIDs", GetAvailableTimezoneIDs), + DECLARE_NAPI_FUNCTION("getAvailableZoneCityIDs", GetAvailableZoneCityIDs), + DECLARE_NAPI_FUNCTION("getCityDisplayName", GetCityDisplayName), + DECLARE_NAPI_FUNCTION("getTimezoneFromCity", GetTimezoneFromCity) + }; + status = napi_define_properties(env, timezone, + sizeof(timezoneProperties) / sizeof(napi_property_descriptor), + timezoneProperties); + if (status != napi_ok) { + HiLog::Error(LABEL, "Failed to set properties of timezone at init"); + return nullptr; + } + return timezone; +} + +napi_value I18nAddon::GetAvailableTimezoneIDs(napi_env env, napi_callback_info info) +{ + std::set timezoneIDs = I18nTimeZone::GetAvailableIDs(); + napi_value result = nullptr; + napi_status status = napi_create_array_with_length(env, timezoneIDs.size(), &result); + if (status != napi_ok) { + HiLog::Error(LABEL, "Failed to create array"); + return nullptr; + } + size_t index = 0; + for (std::set::iterator it = timezoneIDs.begin(); it != timezoneIDs.end(); it++) { + napi_value value = nullptr; + status = napi_create_string_utf8(env, (*it).c_str(), NAPI_AUTO_LENGTH, &value); + if (status != napi_ok) { + HiLog::Error(LABEL, "Failed to create string item"); + return nullptr; + } + status = napi_set_element(env, result, index, value); + if (status != napi_ok) { + HiLog::Error(LABEL, "Failed to set array item"); + return nullptr; + } + index++; + } + return result; +} + +napi_value I18nAddon::GetAvailableZoneCityIDs(napi_env env, napi_callback_info info) +{ + std::vector cityIDs = I18nTimeZone::GetAvailableZoneCityIDs(); + napi_value result = nullptr; + napi_status status = napi_create_array_with_length(env, cityIDs.size(), &result); + if (status != napi_ok) { + HiLog::Error(LABEL, "Failed to create array"); + return nullptr; + } + for (size_t i = 0; i < cityIDs.size(); i++) { + napi_value value = nullptr; + status = napi_create_string_utf8(env, cityIDs[i].c_str(), NAPI_AUTO_LENGTH, &value); + if (status != napi_ok) { + HiLog::Error(LABEL, "Failed to create string item"); + return nullptr; + } + status = napi_set_element(env, result, i, value); + if (status != napi_ok) { + HiLog::Error(LABEL, "Failed to set array item"); + return nullptr; + } + } + return result; +} + +napi_value I18nAddon::GetCityDisplayName(napi_env env, napi_callback_info info) +{ + size_t argc = 2; + napi_value argv[2] = { 0 }; + napi_value thisVar = nullptr; + void *data = nullptr; + napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); + if (status != napi_ok) { + return nullptr; + } + if (argv[0] == nullptr || argv[1] == nullptr) { + return nullptr; + } + napi_valuetype valueType = napi_valuetype::napi_undefined; + napi_typeof(env, argv[0], &valueType); + if (valueType != napi_valuetype::napi_string) { + HiLog::Error(LABEL, "Invalid parameter type"); + return nullptr; + } + int32_t code = 0; + std::string cityID = GetString(env, argv[0], code); + if (code != 0) { + return nullptr; + } + std::string locale = GetString(env, argv[1], code); + if (code != 0) { + return nullptr; + } + std::string name = I18nTimeZone::GetCityDisplayName(cityID, locale); + napi_value result = nullptr; + status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &result); + if (status != napi_ok) { + return nullptr; + } + return result; +} + +napi_value I18nAddon::StaticGetTimeZone(napi_env env, napi_value *argv, bool isZoneID) +{ + napi_value constructor = nullptr; + napi_status status = napi_get_reference_value(env, *g_timezoneConstructor, &constructor); + if (status != napi_ok) { + HiLog::Error(LABEL, "Failed to create reference at StaticGetTimeZone"); + return nullptr; + } + napi_value newArgv[2] = { 0 }; + newArgv[0] = argv[0]; + status = napi_get_boolean(env, isZoneID, &newArgv[1]); + if (status != napi_ok) { + return nullptr; + } + napi_value result = nullptr; + status = napi_new_instance(env, constructor, 2, newArgv, &result); // 2 is parameter num + if (status != napi_ok) { + HiLog::Error(LABEL, "StaticGetTimeZone create instance failed"); + return nullptr; + } + return result; +} + +napi_value I18nAddon::GetTimezoneFromCity(napi_env env, napi_callback_info info) +{ + size_t argc = 1; + napi_value argv[1] = { nullptr }; + napi_value thisVar = nullptr; + void *data = nullptr; + napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); + return StaticGetTimeZone(env, argv, false); +} + napi_value Init(napi_env env, napi_value exports) { napi_value val = I18nAddon::Init(env, exports); -- Gitee