19596a2c1Sopenharmony_ci/* 29596a2c1Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 39596a2c1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 49596a2c1Sopenharmony_ci * you may not use this file except in compliance with the License. 59596a2c1Sopenharmony_ci * You may obtain a copy of the License at 69596a2c1Sopenharmony_ci * 79596a2c1Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 89596a2c1Sopenharmony_ci * 99596a2c1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 109596a2c1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 119596a2c1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 129596a2c1Sopenharmony_ci * See the License for the specific language governing permissions and 139596a2c1Sopenharmony_ci * limitations under the License. 149596a2c1Sopenharmony_ci */ 159596a2c1Sopenharmony_ci#include "character.h" 169596a2c1Sopenharmony_ci#include "error_util.h" 179596a2c1Sopenharmony_ci#include "i18n_hilog.h" 189596a2c1Sopenharmony_ci#include "i18n_timezone_addon.h" 199596a2c1Sopenharmony_ci#include "js_utils.h" 209596a2c1Sopenharmony_ci#include "variable_convertor.h" 219596a2c1Sopenharmony_ci 229596a2c1Sopenharmony_cinamespace OHOS { 239596a2c1Sopenharmony_cinamespace Global { 249596a2c1Sopenharmony_cinamespace I18n { 259596a2c1Sopenharmony_cistatic thread_local napi_ref* g_timezoneConstructor = nullptr; 269596a2c1Sopenharmony_ci 279596a2c1Sopenharmony_ciI18nTimeZoneAddon::I18nTimeZoneAddon() {} 289596a2c1Sopenharmony_ci 299596a2c1Sopenharmony_ciI18nTimeZoneAddon::~I18nTimeZoneAddon() {} 309596a2c1Sopenharmony_ci 319596a2c1Sopenharmony_civoid I18nTimeZoneAddon::Destructor(napi_env env, void *nativeObject, void *hint) 329596a2c1Sopenharmony_ci{ 339596a2c1Sopenharmony_ci if (!nativeObject) { 349596a2c1Sopenharmony_ci return; 359596a2c1Sopenharmony_ci } 369596a2c1Sopenharmony_ci delete reinterpret_cast<I18nTimeZoneAddon *>(nativeObject); 379596a2c1Sopenharmony_ci nativeObject = nullptr; 389596a2c1Sopenharmony_ci} 399596a2c1Sopenharmony_ci 409596a2c1Sopenharmony_cinapi_value I18nTimeZoneAddon::GetI18nTimeZone(napi_env env, napi_callback_info info) 419596a2c1Sopenharmony_ci{ 429596a2c1Sopenharmony_ci size_t argc = 1; 439596a2c1Sopenharmony_ci napi_value argv[1] = { nullptr }; 449596a2c1Sopenharmony_ci napi_value thisVar = nullptr; 459596a2c1Sopenharmony_ci void *data = nullptr; 469596a2c1Sopenharmony_ci napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 479596a2c1Sopenharmony_ci if (!VariableConvertor::CheckNapiValueType(env, argv[0])) { 489596a2c1Sopenharmony_ci napi_create_string_utf8(env, "", NAPI_AUTO_LENGTH, &argv[0]); 499596a2c1Sopenharmony_ci } 509596a2c1Sopenharmony_ci return StaticGetTimeZone(env, argv, true); 519596a2c1Sopenharmony_ci} 529596a2c1Sopenharmony_ci 539596a2c1Sopenharmony_cinapi_value I18nTimeZoneAddon::InitI18nTimeZone(napi_env env, napi_value exports) 549596a2c1Sopenharmony_ci{ 559596a2c1Sopenharmony_ci napi_property_descriptor properties[] = { 569596a2c1Sopenharmony_ci DECLARE_NAPI_FUNCTION("getID", GetID), 579596a2c1Sopenharmony_ci DECLARE_NAPI_FUNCTION("getDisplayName", GetTimeZoneDisplayName), 589596a2c1Sopenharmony_ci DECLARE_NAPI_FUNCTION("getRawOffset", GetRawOffset), 599596a2c1Sopenharmony_ci DECLARE_NAPI_FUNCTION("getOffset", GetOffset), 609596a2c1Sopenharmony_ci }; 619596a2c1Sopenharmony_ci napi_value constructor = nullptr; 629596a2c1Sopenharmony_ci napi_status status = napi_define_class(env, "TimeZone", NAPI_AUTO_LENGTH, I18nTimeZoneConstructor, nullptr, 639596a2c1Sopenharmony_ci sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor); 649596a2c1Sopenharmony_ci if (status != napi_ok) { 659596a2c1Sopenharmony_ci HILOG_ERROR_I18N("InitI18nTimeZone: Failed to define class TimeZone at Init"); 669596a2c1Sopenharmony_ci return nullptr; 679596a2c1Sopenharmony_ci } 689596a2c1Sopenharmony_ci exports = I18nTimeZoneAddon::InitTimeZone(env, exports); 699596a2c1Sopenharmony_ci g_timezoneConstructor = new (std::nothrow) napi_ref; 709596a2c1Sopenharmony_ci if (!g_timezoneConstructor) { 719596a2c1Sopenharmony_ci HILOG_ERROR_I18N("InitI18nTimeZone: Failed to create TimeZone ref at init"); 729596a2c1Sopenharmony_ci return nullptr; 739596a2c1Sopenharmony_ci } 749596a2c1Sopenharmony_ci status = napi_create_reference(env, constructor, 1, g_timezoneConstructor); 759596a2c1Sopenharmony_ci if (status != napi_ok) { 769596a2c1Sopenharmony_ci HILOG_ERROR_I18N("InitI18nTimeZone: Failed to create reference g_timezoneConstructor at init"); 779596a2c1Sopenharmony_ci return nullptr; 789596a2c1Sopenharmony_ci } 799596a2c1Sopenharmony_ci return exports; 809596a2c1Sopenharmony_ci} 819596a2c1Sopenharmony_ci 829596a2c1Sopenharmony_cinapi_value I18nTimeZoneAddon::InitTimeZone(napi_env env, napi_value exports) 839596a2c1Sopenharmony_ci{ 849596a2c1Sopenharmony_ci napi_property_descriptor properties[] = { 859596a2c1Sopenharmony_ci DECLARE_NAPI_STATIC_FUNCTION("getAvailableIDs", GetAvailableTimezoneIDs), 869596a2c1Sopenharmony_ci DECLARE_NAPI_STATIC_FUNCTION("getAvailableZoneCityIDs", GetAvailableZoneCityIDs), 879596a2c1Sopenharmony_ci DECLARE_NAPI_STATIC_FUNCTION("getCityDisplayName", GetCityDisplayName), 889596a2c1Sopenharmony_ci DECLARE_NAPI_STATIC_FUNCTION("getTimezoneFromCity", GetTimezoneFromCity), 899596a2c1Sopenharmony_ci DECLARE_NAPI_STATIC_FUNCTION("getTimezonesByLocation", GetTimezonesByLocation) 909596a2c1Sopenharmony_ci }; 919596a2c1Sopenharmony_ci napi_value constructor = nullptr; 929596a2c1Sopenharmony_ci napi_status status = napi_define_class(env, "I18nTimeZone", NAPI_AUTO_LENGTH, JSUtils::DefaultConstructor, nullptr, 939596a2c1Sopenharmony_ci sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor); 949596a2c1Sopenharmony_ci if (status != napi_ok) { 959596a2c1Sopenharmony_ci HILOG_ERROR_I18N("InitTimeZone: Failed to define class TimeZone."); 969596a2c1Sopenharmony_ci return nullptr; 979596a2c1Sopenharmony_ci } 989596a2c1Sopenharmony_ci status = napi_set_named_property(env, exports, "TimeZone", constructor); 999596a2c1Sopenharmony_ci if (status != napi_ok) { 1009596a2c1Sopenharmony_ci HILOG_ERROR_I18N("InitTimeZone: Set property failed When InitTimeZone."); 1019596a2c1Sopenharmony_ci return nullptr; 1029596a2c1Sopenharmony_ci } 1039596a2c1Sopenharmony_ci return exports; 1049596a2c1Sopenharmony_ci} 1059596a2c1Sopenharmony_ci 1069596a2c1Sopenharmony_cinapi_value I18nTimeZoneAddon::I18nTimeZoneConstructor(napi_env env, napi_callback_info info) 1079596a2c1Sopenharmony_ci{ 1089596a2c1Sopenharmony_ci size_t argc = 2; 1099596a2c1Sopenharmony_ci napi_value argv[2] = { nullptr }; 1109596a2c1Sopenharmony_ci napi_value thisVar = nullptr; 1119596a2c1Sopenharmony_ci void *data = nullptr; 1129596a2c1Sopenharmony_ci napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 1139596a2c1Sopenharmony_ci if (status != napi_ok) { 1149596a2c1Sopenharmony_ci return nullptr; 1159596a2c1Sopenharmony_ci } 1169596a2c1Sopenharmony_ci std::string zoneID = ""; 1179596a2c1Sopenharmony_ci napi_valuetype valueType = napi_valuetype::napi_undefined; 1189596a2c1Sopenharmony_ci if (argc > 0) { 1199596a2c1Sopenharmony_ci napi_typeof(env, argv[0], &valueType); 1209596a2c1Sopenharmony_ci if (valueType != napi_valuetype::napi_string) { 1219596a2c1Sopenharmony_ci return nullptr; 1229596a2c1Sopenharmony_ci } 1239596a2c1Sopenharmony_ci int32_t code = 0; 1249596a2c1Sopenharmony_ci zoneID = VariableConvertor::GetString(env, argv[0], code); 1259596a2c1Sopenharmony_ci if (code != 0) { 1269596a2c1Sopenharmony_ci return nullptr; 1279596a2c1Sopenharmony_ci } 1289596a2c1Sopenharmony_ci } 1299596a2c1Sopenharmony_ci if (argc < FUNC_ARGS_COUNT) { 1309596a2c1Sopenharmony_ci return nullptr; 1319596a2c1Sopenharmony_ci } 1329596a2c1Sopenharmony_ci napi_typeof(env, argv[1], &valueType); 1339596a2c1Sopenharmony_ci if (valueType != napi_valuetype::napi_boolean) { 1349596a2c1Sopenharmony_ci return nullptr; 1359596a2c1Sopenharmony_ci } 1369596a2c1Sopenharmony_ci bool isZoneID = false; 1379596a2c1Sopenharmony_ci status = napi_get_value_bool(env, argv[1], &isZoneID); 1389596a2c1Sopenharmony_ci if (status != napi_ok) { 1399596a2c1Sopenharmony_ci return nullptr; 1409596a2c1Sopenharmony_ci } 1419596a2c1Sopenharmony_ci std::unique_ptr<I18nTimeZoneAddon> obj = std::make_unique<I18nTimeZoneAddon>(); 1429596a2c1Sopenharmony_ci status = 1439596a2c1Sopenharmony_ci napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), I18nTimeZoneAddon::Destructor, nullptr, nullptr); 1449596a2c1Sopenharmony_ci if (status != napi_ok) { 1459596a2c1Sopenharmony_ci return nullptr; 1469596a2c1Sopenharmony_ci } 1479596a2c1Sopenharmony_ci obj->timezone_ = I18nTimeZone::CreateInstance(zoneID, isZoneID); 1489596a2c1Sopenharmony_ci if (!obj->timezone_) { 1499596a2c1Sopenharmony_ci return nullptr; 1509596a2c1Sopenharmony_ci } 1519596a2c1Sopenharmony_ci obj.release(); 1529596a2c1Sopenharmony_ci return thisVar; 1539596a2c1Sopenharmony_ci} 1549596a2c1Sopenharmony_ci 1559596a2c1Sopenharmony_cinapi_value I18nTimeZoneAddon::GetAvailableTimezoneIDs(napi_env env, napi_callback_info info) 1569596a2c1Sopenharmony_ci{ 1579596a2c1Sopenharmony_ci I18nErrorCode errorCode = I18nErrorCode::SUCCESS; 1589596a2c1Sopenharmony_ci std::set<std::string> timezoneIDs = I18nTimeZone::GetAvailableIDs(errorCode); 1599596a2c1Sopenharmony_ci if (errorCode != I18nErrorCode::SUCCESS) { 1609596a2c1Sopenharmony_ci return nullptr; 1619596a2c1Sopenharmony_ci } 1629596a2c1Sopenharmony_ci napi_value result = nullptr; 1639596a2c1Sopenharmony_ci napi_status status = napi_create_array_with_length(env, timezoneIDs.size(), &result); 1649596a2c1Sopenharmony_ci if (status != napi_ok) { 1659596a2c1Sopenharmony_ci HILOG_ERROR_I18N("GetAvailableTimezoneIDs: Failed to create array"); 1669596a2c1Sopenharmony_ci return nullptr; 1679596a2c1Sopenharmony_ci } 1689596a2c1Sopenharmony_ci size_t index = 0; 1699596a2c1Sopenharmony_ci for (std::set<std::string>::iterator it = timezoneIDs.begin(); it != timezoneIDs.end(); ++it) { 1709596a2c1Sopenharmony_ci napi_value value = nullptr; 1719596a2c1Sopenharmony_ci status = napi_create_string_utf8(env, (*it).c_str(), NAPI_AUTO_LENGTH, &value); 1729596a2c1Sopenharmony_ci if (status != napi_ok) { 1739596a2c1Sopenharmony_ci HILOG_ERROR_I18N("Failed to create string item"); 1749596a2c1Sopenharmony_ci return nullptr; 1759596a2c1Sopenharmony_ci } 1769596a2c1Sopenharmony_ci status = napi_set_element(env, result, index, value); 1779596a2c1Sopenharmony_ci if (status != napi_ok) { 1789596a2c1Sopenharmony_ci HILOG_ERROR_I18N("Failed to set array item"); 1799596a2c1Sopenharmony_ci return nullptr; 1809596a2c1Sopenharmony_ci } 1819596a2c1Sopenharmony_ci ++index; 1829596a2c1Sopenharmony_ci } 1839596a2c1Sopenharmony_ci return result; 1849596a2c1Sopenharmony_ci} 1859596a2c1Sopenharmony_ci 1869596a2c1Sopenharmony_cinapi_value I18nTimeZoneAddon::GetAvailableZoneCityIDs(napi_env env, napi_callback_info info) 1879596a2c1Sopenharmony_ci{ 1889596a2c1Sopenharmony_ci std::set<std::string> cityIDs = I18nTimeZone::GetAvailableZoneCityIDs(); 1899596a2c1Sopenharmony_ci napi_value result = nullptr; 1909596a2c1Sopenharmony_ci napi_status status = napi_create_array_with_length(env, cityIDs.size(), &result); 1919596a2c1Sopenharmony_ci if (status != napi_ok) { 1929596a2c1Sopenharmony_ci HILOG_ERROR_I18N("GetAvailableZoneCityIDs: Failed to create array"); 1939596a2c1Sopenharmony_ci return nullptr; 1949596a2c1Sopenharmony_ci } 1959596a2c1Sopenharmony_ci size_t index = 0; 1969596a2c1Sopenharmony_ci for (auto it = cityIDs.begin(); it != cityIDs.end(); ++it) { 1979596a2c1Sopenharmony_ci napi_value value = nullptr; 1989596a2c1Sopenharmony_ci status = napi_create_string_utf8(env, (*it).c_str(), NAPI_AUTO_LENGTH, &value); 1999596a2c1Sopenharmony_ci if (status != napi_ok) { 2009596a2c1Sopenharmony_ci HILOG_ERROR_I18N("GetAvailableZoneCityIDs: Failed to create string item"); 2019596a2c1Sopenharmony_ci return nullptr; 2029596a2c1Sopenharmony_ci } 2039596a2c1Sopenharmony_ci status = napi_set_element(env, result, index, value); 2049596a2c1Sopenharmony_ci if (status != napi_ok) { 2059596a2c1Sopenharmony_ci HILOG_ERROR_I18N("GetAvailableZoneCityIDs: Failed to set array item"); 2069596a2c1Sopenharmony_ci return nullptr; 2079596a2c1Sopenharmony_ci } 2089596a2c1Sopenharmony_ci ++index; 2099596a2c1Sopenharmony_ci } 2109596a2c1Sopenharmony_ci return result; 2119596a2c1Sopenharmony_ci} 2129596a2c1Sopenharmony_ci 2139596a2c1Sopenharmony_cinapi_value I18nTimeZoneAddon::GetCityDisplayName(napi_env env, napi_callback_info info) 2149596a2c1Sopenharmony_ci{ 2159596a2c1Sopenharmony_ci size_t argc = 2; 2169596a2c1Sopenharmony_ci napi_value argv[2] = { 0 }; 2179596a2c1Sopenharmony_ci napi_value thisVar = nullptr; 2189596a2c1Sopenharmony_ci void *data = nullptr; 2199596a2c1Sopenharmony_ci napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 2209596a2c1Sopenharmony_ci if (status != napi_ok) { 2219596a2c1Sopenharmony_ci return nullptr; 2229596a2c1Sopenharmony_ci } 2239596a2c1Sopenharmony_ci if (argc < FUNC_ARGS_COUNT) { 2249596a2c1Sopenharmony_ci return nullptr; 2259596a2c1Sopenharmony_ci } 2269596a2c1Sopenharmony_ci napi_valuetype valueType = napi_valuetype::napi_undefined; 2279596a2c1Sopenharmony_ci napi_typeof(env, argv[0], &valueType); 2289596a2c1Sopenharmony_ci if (valueType != napi_valuetype::napi_string) { 2299596a2c1Sopenharmony_ci HILOG_ERROR_I18N("GetCityDisplayName: Invalid parameter type"); 2309596a2c1Sopenharmony_ci return nullptr; 2319596a2c1Sopenharmony_ci } 2329596a2c1Sopenharmony_ci int32_t code = 0; 2339596a2c1Sopenharmony_ci std::string cityID = VariableConvertor::GetString(env, argv[0], code); 2349596a2c1Sopenharmony_ci if (code != 0) { 2359596a2c1Sopenharmony_ci return nullptr; 2369596a2c1Sopenharmony_ci } 2379596a2c1Sopenharmony_ci std::string locale = VariableConvertor::GetString(env, argv[1], code); 2389596a2c1Sopenharmony_ci if (code != 0) { 2399596a2c1Sopenharmony_ci return nullptr; 2409596a2c1Sopenharmony_ci } 2419596a2c1Sopenharmony_ci std::string name = I18nTimeZone::GetCityDisplayName(cityID, locale); 2429596a2c1Sopenharmony_ci napi_value result = nullptr; 2439596a2c1Sopenharmony_ci status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &result); 2449596a2c1Sopenharmony_ci if (status != napi_ok) { 2459596a2c1Sopenharmony_ci return nullptr; 2469596a2c1Sopenharmony_ci } 2479596a2c1Sopenharmony_ci return result; 2489596a2c1Sopenharmony_ci} 2499596a2c1Sopenharmony_ci 2509596a2c1Sopenharmony_cinapi_value I18nTimeZoneAddon::GetTimezoneFromCity(napi_env env, napi_callback_info info) 2519596a2c1Sopenharmony_ci{ 2529596a2c1Sopenharmony_ci size_t argc = 1; 2539596a2c1Sopenharmony_ci napi_value argv[1] = { nullptr }; 2549596a2c1Sopenharmony_ci napi_value thisVar = nullptr; 2559596a2c1Sopenharmony_ci void *data = nullptr; 2569596a2c1Sopenharmony_ci napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 2579596a2c1Sopenharmony_ci return StaticGetTimeZone(env, argv, false); 2589596a2c1Sopenharmony_ci} 2599596a2c1Sopenharmony_ci 2609596a2c1Sopenharmony_cinapi_value I18nTimeZoneAddon::GetTimezonesByLocation(napi_env env, napi_callback_info info) 2619596a2c1Sopenharmony_ci{ 2629596a2c1Sopenharmony_ci size_t argc = 2; 2639596a2c1Sopenharmony_ci napi_value argv[2] = {0, 0}; 2649596a2c1Sopenharmony_ci napi_value thisVar = nullptr; 2659596a2c1Sopenharmony_ci void *data = nullptr; 2669596a2c1Sopenharmony_ci napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 2679596a2c1Sopenharmony_ci if (status != napi_ok) { 2689596a2c1Sopenharmony_ci return nullptr; 2699596a2c1Sopenharmony_ci } 2709596a2c1Sopenharmony_ci if (argc < FUNC_ARGS_COUNT) { 2719596a2c1Sopenharmony_ci HILOG_ERROR_I18N("GetTimezonesByLocation: Missing parameter"); 2729596a2c1Sopenharmony_ci ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "longitude or latitude", "", true); 2739596a2c1Sopenharmony_ci return nullptr; 2749596a2c1Sopenharmony_ci } 2759596a2c1Sopenharmony_ci double x; 2769596a2c1Sopenharmony_ci double y; 2779596a2c1Sopenharmony_ci VariableConvertor::VerifyType(env, "longitude", "number", argv[0]); 2789596a2c1Sopenharmony_ci VariableConvertor::VerifyType(env, "latitude", "number", argv[1]); 2799596a2c1Sopenharmony_ci if (!CheckLongitudeTypeAndScope(env, argv[0], x) || 2809596a2c1Sopenharmony_ci !CheckLatitudeTypeAndScope(env, argv[1], y)) { 2819596a2c1Sopenharmony_ci ErrorUtil::NapiThrow(env, I18N_NOT_VALID, "longitude or latitude", "a valid value", true); 2829596a2c1Sopenharmony_ci return nullptr; 2839596a2c1Sopenharmony_ci } 2849596a2c1Sopenharmony_ci napi_value timezoneList = nullptr; 2859596a2c1Sopenharmony_ci napi_create_array(env, &timezoneList); 2869596a2c1Sopenharmony_ci std::vector<std::string> tempList = I18nTimeZone::GetTimezoneIdByLocation(x, y); 2879596a2c1Sopenharmony_ci for (size_t i = 0; i < tempList.size(); i++) { 2889596a2c1Sopenharmony_ci napi_value timezoneId = nullptr; 2899596a2c1Sopenharmony_ci status = napi_create_string_utf8(env, tempList[i].c_str(), NAPI_AUTO_LENGTH, &timezoneId); 2909596a2c1Sopenharmony_ci if (status != napi_ok) { 2919596a2c1Sopenharmony_ci return nullptr; 2929596a2c1Sopenharmony_ci } 2939596a2c1Sopenharmony_ci napi_value argTimeZoneId[1] = { timezoneId }; 2949596a2c1Sopenharmony_ci napi_value timezone = StaticGetTimeZone(env, argTimeZoneId, true); 2959596a2c1Sopenharmony_ci status = napi_set_element(env, timezoneList, i, timezone); 2969596a2c1Sopenharmony_ci if (status != napi_ok) { 2979596a2c1Sopenharmony_ci return nullptr; 2989596a2c1Sopenharmony_ci } 2999596a2c1Sopenharmony_ci } 3009596a2c1Sopenharmony_ci 3019596a2c1Sopenharmony_ci return timezoneList; 3029596a2c1Sopenharmony_ci} 3039596a2c1Sopenharmony_ci 3049596a2c1Sopenharmony_cibool I18nTimeZoneAddon::CheckLongitudeTypeAndScope(napi_env env, napi_value argv, double &x) 3059596a2c1Sopenharmony_ci{ 3069596a2c1Sopenharmony_ci napi_status status = napi_get_value_double(env, argv, &x); 3079596a2c1Sopenharmony_ci if (status != napi_ok) { 3089596a2c1Sopenharmony_ci HILOG_ERROR_I18N("GetTimezonesByLocation: Parse first argument x failed"); 3099596a2c1Sopenharmony_ci return false; 3109596a2c1Sopenharmony_ci } 3119596a2c1Sopenharmony_ci // -180 and 179.9 is the scope of longitude 3129596a2c1Sopenharmony_ci if (x < -180 || x > 179.9) { 3139596a2c1Sopenharmony_ci HILOG_ERROR_I18N("GetTimezonesByLocation: Args x exceed it's scope."); 3149596a2c1Sopenharmony_ci return false; 3159596a2c1Sopenharmony_ci } 3169596a2c1Sopenharmony_ci return true; 3179596a2c1Sopenharmony_ci} 3189596a2c1Sopenharmony_ci 3199596a2c1Sopenharmony_cibool I18nTimeZoneAddon::CheckLatitudeTypeAndScope(napi_env env, napi_value argv, double &y) 3209596a2c1Sopenharmony_ci{ 3219596a2c1Sopenharmony_ci napi_status status = napi_get_value_double(env, argv, &y); 3229596a2c1Sopenharmony_ci if (status != napi_ok) { 3239596a2c1Sopenharmony_ci HILOG_ERROR_I18N("GetTimezonesByLocation: Parse second argument y failed"); 3249596a2c1Sopenharmony_ci return false; 3259596a2c1Sopenharmony_ci } 3269596a2c1Sopenharmony_ci // -90 and 89.9 is the scope of latitude 3279596a2c1Sopenharmony_ci if (y < -90 || y > 89.9) { 3289596a2c1Sopenharmony_ci HILOG_ERROR_I18N("GetTimezonesByLocation: Args y exceed it's scope."); 3299596a2c1Sopenharmony_ci return false; 3309596a2c1Sopenharmony_ci } 3319596a2c1Sopenharmony_ci return true; 3329596a2c1Sopenharmony_ci} 3339596a2c1Sopenharmony_ci 3349596a2c1Sopenharmony_cinapi_value I18nTimeZoneAddon::GetID(napi_env env, napi_callback_info info) 3359596a2c1Sopenharmony_ci{ 3369596a2c1Sopenharmony_ci size_t argc = 0; 3379596a2c1Sopenharmony_ci napi_value *argv = nullptr; 3389596a2c1Sopenharmony_ci napi_value thisVar = nullptr; 3399596a2c1Sopenharmony_ci void *data = nullptr; 3409596a2c1Sopenharmony_ci napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 3419596a2c1Sopenharmony_ci I18nTimeZoneAddon *obj = nullptr; 3429596a2c1Sopenharmony_ci napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj)); 3439596a2c1Sopenharmony_ci if (status != napi_ok || !obj || !obj->timezone_) { 3449596a2c1Sopenharmony_ci HILOG_ERROR_I18N("GetID: Get TimeZone object failed"); 3459596a2c1Sopenharmony_ci return nullptr; 3469596a2c1Sopenharmony_ci } 3479596a2c1Sopenharmony_ci std::string result = obj->timezone_->GetID(); 3489596a2c1Sopenharmony_ci napi_value value = nullptr; 3499596a2c1Sopenharmony_ci status = napi_create_string_utf8(env, result.c_str(), NAPI_AUTO_LENGTH, &value); 3509596a2c1Sopenharmony_ci if (status != napi_ok) { 3519596a2c1Sopenharmony_ci HILOG_ERROR_I18N("GetID: Create result failed"); 3529596a2c1Sopenharmony_ci return nullptr; 3539596a2c1Sopenharmony_ci } 3549596a2c1Sopenharmony_ci return value; 3559596a2c1Sopenharmony_ci} 3569596a2c1Sopenharmony_ci 3579596a2c1Sopenharmony_cinapi_value I18nTimeZoneAddon::GetTimeZoneDisplayName(napi_env env, napi_callback_info info) 3589596a2c1Sopenharmony_ci{ 3599596a2c1Sopenharmony_ci size_t argc = 2; 3609596a2c1Sopenharmony_ci napi_value argv[2] = { 0 }; 3619596a2c1Sopenharmony_ci napi_value thisVar = nullptr; 3629596a2c1Sopenharmony_ci void *data = nullptr; 3639596a2c1Sopenharmony_ci napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 3649596a2c1Sopenharmony_ci if (status != napi_ok) { 3659596a2c1Sopenharmony_ci return nullptr; 3669596a2c1Sopenharmony_ci } 3679596a2c1Sopenharmony_ci 3689596a2c1Sopenharmony_ci I18nTimeZoneAddon *obj = nullptr; 3699596a2c1Sopenharmony_ci status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj)); 3709596a2c1Sopenharmony_ci if (status != napi_ok || !obj || !obj->timezone_) { 3719596a2c1Sopenharmony_ci HILOG_ERROR_I18N("GetTimeZoneDisplayName: Get TimeZone object failed"); 3729596a2c1Sopenharmony_ci return nullptr; 3739596a2c1Sopenharmony_ci } 3749596a2c1Sopenharmony_ci 3759596a2c1Sopenharmony_ci std::string locale; 3769596a2c1Sopenharmony_ci bool isDST = false; 3779596a2c1Sopenharmony_ci int32_t parameterStatus = GetParameter(env, argv, locale, isDST); 3789596a2c1Sopenharmony_ci 3799596a2c1Sopenharmony_ci std::string result; 3809596a2c1Sopenharmony_ci if (parameterStatus == -1) { // -1 represents Invalid parameter. 3819596a2c1Sopenharmony_ci HILOG_ERROR_I18N("GetTimeZoneDisplayName: Parameter type does not match"); 3829596a2c1Sopenharmony_ci return nullptr; 3839596a2c1Sopenharmony_ci } else if (parameterStatus == 0) { 3849596a2c1Sopenharmony_ci result = obj->timezone_->GetDisplayName(); 3859596a2c1Sopenharmony_ci } else if (parameterStatus == 1) { // 1 represents one string parameter. 3869596a2c1Sopenharmony_ci result = obj->timezone_->GetDisplayName(locale); 3879596a2c1Sopenharmony_ci } else if (parameterStatus == 2) { // 2 represents one boolean parameter. 3889596a2c1Sopenharmony_ci result = obj->timezone_->GetDisplayName(isDST); 3899596a2c1Sopenharmony_ci } else { 3909596a2c1Sopenharmony_ci result = obj->timezone_->GetDisplayName(locale, isDST); 3919596a2c1Sopenharmony_ci } 3929596a2c1Sopenharmony_ci 3939596a2c1Sopenharmony_ci napi_value value = nullptr; 3949596a2c1Sopenharmony_ci status = napi_create_string_utf8(env, result.c_str(), NAPI_AUTO_LENGTH, &value); 3959596a2c1Sopenharmony_ci if (status != napi_ok) { 3969596a2c1Sopenharmony_ci HILOG_ERROR_I18N("GetTimeZoneDisplayName: Create result failed"); 3979596a2c1Sopenharmony_ci return nullptr; 3989596a2c1Sopenharmony_ci } 3999596a2c1Sopenharmony_ci return value; 4009596a2c1Sopenharmony_ci} 4019596a2c1Sopenharmony_ci 4029596a2c1Sopenharmony_cinapi_value I18nTimeZoneAddon::GetRawOffset(napi_env env, napi_callback_info info) 4039596a2c1Sopenharmony_ci{ 4049596a2c1Sopenharmony_ci size_t argc = 0; 4059596a2c1Sopenharmony_ci napi_value *argv = nullptr; 4069596a2c1Sopenharmony_ci napi_value thisVar = nullptr; 4079596a2c1Sopenharmony_ci void *data = nullptr; 4089596a2c1Sopenharmony_ci napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 4099596a2c1Sopenharmony_ci I18nTimeZoneAddon *obj = nullptr; 4109596a2c1Sopenharmony_ci napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj)); 4119596a2c1Sopenharmony_ci if (status != napi_ok || !obj || !obj->timezone_) { 4129596a2c1Sopenharmony_ci HILOG_ERROR_I18N("GetRawOffset: Get TimeZone object failed"); 4139596a2c1Sopenharmony_ci return nullptr; 4149596a2c1Sopenharmony_ci } 4159596a2c1Sopenharmony_ci int32_t result = obj->timezone_->GetRawOffset(); 4169596a2c1Sopenharmony_ci napi_value value = nullptr; 4179596a2c1Sopenharmony_ci status = napi_create_int32(env, result, &value); 4189596a2c1Sopenharmony_ci if (status != napi_ok) { 4199596a2c1Sopenharmony_ci HILOG_ERROR_I18N("GetRawOffset: Create result failed"); 4209596a2c1Sopenharmony_ci return nullptr; 4219596a2c1Sopenharmony_ci } 4229596a2c1Sopenharmony_ci return value; 4239596a2c1Sopenharmony_ci} 4249596a2c1Sopenharmony_ci 4259596a2c1Sopenharmony_cinapi_value I18nTimeZoneAddon::GetOffset(napi_env env, napi_callback_info info) 4269596a2c1Sopenharmony_ci{ 4279596a2c1Sopenharmony_ci size_t argc = 1; 4289596a2c1Sopenharmony_ci napi_value argv[1] = { 0 }; 4299596a2c1Sopenharmony_ci napi_value thisVar = nullptr; 4309596a2c1Sopenharmony_ci void *data = nullptr; 4319596a2c1Sopenharmony_ci napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 4329596a2c1Sopenharmony_ci if (status != napi_ok) { 4339596a2c1Sopenharmony_ci return nullptr; 4349596a2c1Sopenharmony_ci } 4359596a2c1Sopenharmony_ci 4369596a2c1Sopenharmony_ci double date = 0; 4379596a2c1Sopenharmony_ci if (VariableConvertor::CheckNapiValueType(env, argv[0])) { 4389596a2c1Sopenharmony_ci napi_valuetype valueType = napi_valuetype::napi_undefined; 4399596a2c1Sopenharmony_ci napi_typeof(env, argv[0], &valueType); 4409596a2c1Sopenharmony_ci if (valueType != napi_valuetype::napi_number) { 4419596a2c1Sopenharmony_ci HILOG_ERROR_I18N("GetOffset: Invalid parameter type"); 4429596a2c1Sopenharmony_ci return nullptr; 4439596a2c1Sopenharmony_ci } 4449596a2c1Sopenharmony_ci status = napi_get_value_double(env, argv[0], &date); 4459596a2c1Sopenharmony_ci if (status != napi_ok) { 4469596a2c1Sopenharmony_ci HILOG_ERROR_I18N("Get parameter date failed"); 4479596a2c1Sopenharmony_ci return nullptr; 4489596a2c1Sopenharmony_ci } 4499596a2c1Sopenharmony_ci } else { 4509596a2c1Sopenharmony_ci auto time = std::chrono::system_clock::now(); 4519596a2c1Sopenharmony_ci auto since_epoch = time.time_since_epoch(); 4529596a2c1Sopenharmony_ci auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(since_epoch); 4539596a2c1Sopenharmony_ci date = (double)millis.count(); 4549596a2c1Sopenharmony_ci } 4559596a2c1Sopenharmony_ci 4569596a2c1Sopenharmony_ci I18nTimeZoneAddon *obj = nullptr; 4579596a2c1Sopenharmony_ci status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj)); 4589596a2c1Sopenharmony_ci if (status != napi_ok || !obj || !obj->timezone_) { 4599596a2c1Sopenharmony_ci HILOG_ERROR_I18N("GetOffset: Get TimeZone object failed"); 4609596a2c1Sopenharmony_ci return nullptr; 4619596a2c1Sopenharmony_ci } 4629596a2c1Sopenharmony_ci int32_t result = obj->timezone_->GetOffset(date); 4639596a2c1Sopenharmony_ci napi_value value = nullptr; 4649596a2c1Sopenharmony_ci status = napi_create_int32(env, result, &value); 4659596a2c1Sopenharmony_ci if (status != napi_ok) { 4669596a2c1Sopenharmony_ci HILOG_ERROR_I18N("GetOffset: Create result failed"); 4679596a2c1Sopenharmony_ci return nullptr; 4689596a2c1Sopenharmony_ci } 4699596a2c1Sopenharmony_ci return value; 4709596a2c1Sopenharmony_ci} 4719596a2c1Sopenharmony_ci 4729596a2c1Sopenharmony_cinapi_value I18nTimeZoneAddon::StaticGetTimeZone(napi_env env, napi_value *argv, bool isZoneID) 4739596a2c1Sopenharmony_ci{ 4749596a2c1Sopenharmony_ci napi_value constructor = nullptr; 4759596a2c1Sopenharmony_ci napi_status status = napi_get_reference_value(env, *g_timezoneConstructor, &constructor); 4769596a2c1Sopenharmony_ci if (status != napi_ok) { 4779596a2c1Sopenharmony_ci HILOG_ERROR_I18N("Failed to create reference at StaticGetTimeZone"); 4789596a2c1Sopenharmony_ci return nullptr; 4799596a2c1Sopenharmony_ci } 4809596a2c1Sopenharmony_ci napi_value newArgv[2] = { 0 }; 4819596a2c1Sopenharmony_ci newArgv[0] = argv[0]; 4829596a2c1Sopenharmony_ci status = napi_get_boolean(env, isZoneID, &newArgv[1]); 4839596a2c1Sopenharmony_ci if (status != napi_ok) { 4849596a2c1Sopenharmony_ci return nullptr; 4859596a2c1Sopenharmony_ci } 4869596a2c1Sopenharmony_ci napi_value result = nullptr; 4879596a2c1Sopenharmony_ci status = napi_new_instance(env, constructor, 2, newArgv, &result); // 2 is parameter num 4889596a2c1Sopenharmony_ci if (status != napi_ok) { 4899596a2c1Sopenharmony_ci HILOG_ERROR_I18N("StaticGetTimeZone create instance failed"); 4909596a2c1Sopenharmony_ci return nullptr; 4919596a2c1Sopenharmony_ci } 4929596a2c1Sopenharmony_ci return result; 4939596a2c1Sopenharmony_ci} 4949596a2c1Sopenharmony_ci 4959596a2c1Sopenharmony_ciint32_t I18nTimeZoneAddon::GetParameter(napi_env env, napi_value *argv, std::string &localeStr, bool &isDST) 4969596a2c1Sopenharmony_ci{ 4979596a2c1Sopenharmony_ci napi_status status = napi_ok; 4989596a2c1Sopenharmony_ci if (VariableConvertor::CheckNapiValueType(env, argv[1])) { 4999596a2c1Sopenharmony_ci napi_valuetype valueType0 = napi_valuetype::napi_undefined; 5009596a2c1Sopenharmony_ci napi_valuetype valueType1 = napi_valuetype::napi_undefined; 5019596a2c1Sopenharmony_ci napi_typeof(env, argv[0], &valueType0); // 0 represents first parameter 5029596a2c1Sopenharmony_ci napi_typeof(env, argv[1], &valueType1); // 1 represents second parameter 5039596a2c1Sopenharmony_ci bool firstParamFlag = VariableConvertor::CheckNapiValueType(env, argv[0]); 5049596a2c1Sopenharmony_ci if (valueType1 == napi_valuetype::napi_boolean) { 5059596a2c1Sopenharmony_ci status = napi_get_value_bool(env, argv[1], &isDST); 5069596a2c1Sopenharmony_ci if (status != napi_ok) { 5079596a2c1Sopenharmony_ci return -1; // -1 represents Invalid parameter. 5089596a2c1Sopenharmony_ci } else if (!firstParamFlag) { 5099596a2c1Sopenharmony_ci return 2; // 2 represents one boolean parameter. 5109596a2c1Sopenharmony_ci } 5119596a2c1Sopenharmony_ci if (valueType0 == napi_valuetype::napi_string && 5129596a2c1Sopenharmony_ci GetStringFromJS(env, argv[0], localeStr)) { 5139596a2c1Sopenharmony_ci return 3; // 3 represents one string parameter and one bool parameter. 5149596a2c1Sopenharmony_ci } 5159596a2c1Sopenharmony_ci } 5169596a2c1Sopenharmony_ci return -1; // -1 represents Invalid parameter. 5179596a2c1Sopenharmony_ci } 5189596a2c1Sopenharmony_ci return GetFirstParameter(env, argv[0], localeStr, isDST); 5199596a2c1Sopenharmony_ci} 5209596a2c1Sopenharmony_ci 5219596a2c1Sopenharmony_cibool I18nTimeZoneAddon::GetStringFromJS(napi_env env, napi_value argv, std::string &jsString) 5229596a2c1Sopenharmony_ci{ 5239596a2c1Sopenharmony_ci size_t len = 0; 5249596a2c1Sopenharmony_ci napi_status status = napi_get_value_string_utf8(env, argv, nullptr, 0, &len); 5259596a2c1Sopenharmony_ci if (status != napi_ok) { 5269596a2c1Sopenharmony_ci HILOG_ERROR_I18N("Failed to get string length"); 5279596a2c1Sopenharmony_ci return false; 5289596a2c1Sopenharmony_ci } 5299596a2c1Sopenharmony_ci std::vector<char> argvBuf(len + 1); 5309596a2c1Sopenharmony_ci status = napi_get_value_string_utf8(env, argv, argvBuf.data(), len + 1, &len); 5319596a2c1Sopenharmony_ci if (status != napi_ok) { 5329596a2c1Sopenharmony_ci HILOG_ERROR_I18N("Failed to get string item"); 5339596a2c1Sopenharmony_ci return false; 5349596a2c1Sopenharmony_ci } 5359596a2c1Sopenharmony_ci jsString = argvBuf.data(); 5369596a2c1Sopenharmony_ci return true; 5379596a2c1Sopenharmony_ci} 5389596a2c1Sopenharmony_ci 5399596a2c1Sopenharmony_ciint32_t I18nTimeZoneAddon::GetFirstParameter(napi_env env, napi_value value, std::string &localeStr, bool &isDST) 5409596a2c1Sopenharmony_ci{ 5419596a2c1Sopenharmony_ci if (!VariableConvertor::CheckNapiValueType(env, value)) { 5429596a2c1Sopenharmony_ci return 0; // 0 represents no parameter. 5439596a2c1Sopenharmony_ci } else { 5449596a2c1Sopenharmony_ci napi_status status = napi_ok; 5459596a2c1Sopenharmony_ci napi_valuetype valueType = napi_valuetype::napi_undefined; 5469596a2c1Sopenharmony_ci napi_typeof(env, value, &valueType); 5479596a2c1Sopenharmony_ci if (valueType == napi_valuetype::napi_string) { 5489596a2c1Sopenharmony_ci bool valid = GetStringFromJS(env, value, localeStr); 5499596a2c1Sopenharmony_ci // -1 represents Invalid parameter. 5509596a2c1Sopenharmony_ci // 1 represents one string parameter. 5519596a2c1Sopenharmony_ci return !valid ? -1 : 1; 5529596a2c1Sopenharmony_ci } else if (valueType == napi_valuetype::napi_boolean) { 5539596a2c1Sopenharmony_ci status = napi_get_value_bool(env, value, &isDST); 5549596a2c1Sopenharmony_ci // -1 represents Invalid parameter. 5559596a2c1Sopenharmony_ci // 2 represents one boolean parameter. 5569596a2c1Sopenharmony_ci return (status != napi_ok) ? -1 : 2; 5579596a2c1Sopenharmony_ci } 5589596a2c1Sopenharmony_ci return -1; // -1 represents Invalid parameter. 5599596a2c1Sopenharmony_ci } 5609596a2c1Sopenharmony_ci} 5619596a2c1Sopenharmony_ci} // namespace I18n 5629596a2c1Sopenharmony_ci} // namespace Global 5639596a2c1Sopenharmony_ci} // namespace OHOS