1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "character.h"
16 #include "error_util.h"
17 #include "i18n_hilog.h"
18 #include "i18n_timezone_addon.h"
19 #include "js_utils.h"
20 #include "variable_convertor.h"
21 
22 namespace OHOS {
23 namespace Global {
24 namespace I18n {
25 static thread_local napi_ref* g_timezoneConstructor = nullptr;
26 
I18nTimeZoneAddon()27 I18nTimeZoneAddon::I18nTimeZoneAddon() {}
28 
~I18nTimeZoneAddon()29 I18nTimeZoneAddon::~I18nTimeZoneAddon() {}
30 
Destructor(napi_env env,void * nativeObject,void * hint)31 void I18nTimeZoneAddon::Destructor(napi_env env, void *nativeObject, void *hint)
32 {
33     if (!nativeObject) {
34         return;
35     }
36     delete reinterpret_cast<I18nTimeZoneAddon *>(nativeObject);
37     nativeObject = nullptr;
38 }
39 
GetI18nTimeZone(napi_env env,napi_callback_info info)40 napi_value I18nTimeZoneAddon::GetI18nTimeZone(napi_env env, napi_callback_info info)
41 {
42     size_t argc = 1;
43     napi_value argv[1] = { nullptr };
44     napi_value thisVar = nullptr;
45     void *data = nullptr;
46     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
47     if (!VariableConvertor::CheckNapiValueType(env, argv[0])) {
48         napi_create_string_utf8(env, "", NAPI_AUTO_LENGTH, &argv[0]);
49     }
50     return StaticGetTimeZone(env, argv, true);
51 }
52 
InitI18nTimeZone(napi_env env,napi_value exports)53 napi_value I18nTimeZoneAddon::InitI18nTimeZone(napi_env env, napi_value exports)
54 {
55     napi_property_descriptor properties[] = {
56         DECLARE_NAPI_FUNCTION("getID", GetID),
57         DECLARE_NAPI_FUNCTION("getDisplayName", GetTimeZoneDisplayName),
58         DECLARE_NAPI_FUNCTION("getRawOffset", GetRawOffset),
59         DECLARE_NAPI_FUNCTION("getOffset", GetOffset),
60     };
61     napi_value constructor = nullptr;
62     napi_status status = napi_define_class(env, "TimeZone", NAPI_AUTO_LENGTH, I18nTimeZoneConstructor, nullptr,
63         sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
64     if (status != napi_ok) {
65         HILOG_ERROR_I18N("InitI18nTimeZone: Failed to define class TimeZone at Init");
66         return nullptr;
67     }
68     exports = I18nTimeZoneAddon::InitTimeZone(env, exports);
69     g_timezoneConstructor = new (std::nothrow) napi_ref;
70     if (!g_timezoneConstructor) {
71         HILOG_ERROR_I18N("InitI18nTimeZone: Failed to create TimeZone ref at init");
72         return nullptr;
73     }
74     status = napi_create_reference(env, constructor, 1, g_timezoneConstructor);
75     if (status != napi_ok) {
76         HILOG_ERROR_I18N("InitI18nTimeZone: Failed to create reference g_timezoneConstructor at init");
77         return nullptr;
78     }
79     return exports;
80 }
81 
InitTimeZone(napi_env env,napi_value exports)82 napi_value I18nTimeZoneAddon::InitTimeZone(napi_env env, napi_value exports)
83 {
84     napi_property_descriptor properties[] = {
85         DECLARE_NAPI_STATIC_FUNCTION("getAvailableIDs", GetAvailableTimezoneIDs),
86         DECLARE_NAPI_STATIC_FUNCTION("getAvailableZoneCityIDs", GetAvailableZoneCityIDs),
87         DECLARE_NAPI_STATIC_FUNCTION("getCityDisplayName", GetCityDisplayName),
88         DECLARE_NAPI_STATIC_FUNCTION("getTimezoneFromCity", GetTimezoneFromCity),
89         DECLARE_NAPI_STATIC_FUNCTION("getTimezonesByLocation", GetTimezonesByLocation)
90     };
91     napi_value constructor = nullptr;
92     napi_status status = napi_define_class(env, "I18nTimeZone", NAPI_AUTO_LENGTH, JSUtils::DefaultConstructor, nullptr,
93         sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
94     if (status != napi_ok) {
95         HILOG_ERROR_I18N("InitTimeZone: Failed to define class TimeZone.");
96         return nullptr;
97     }
98     status = napi_set_named_property(env, exports, "TimeZone", constructor);
99     if (status != napi_ok) {
100         HILOG_ERROR_I18N("InitTimeZone: Set property failed When InitTimeZone.");
101         return nullptr;
102     }
103     return exports;
104 }
105 
I18nTimeZoneConstructor(napi_env env,napi_callback_info info)106 napi_value I18nTimeZoneAddon::I18nTimeZoneConstructor(napi_env env, napi_callback_info info)
107 {
108     size_t argc = 2;
109     napi_value argv[2] = { nullptr };
110     napi_value thisVar = nullptr;
111     void *data = nullptr;
112     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
113     if (status != napi_ok) {
114         return nullptr;
115     }
116     std::string zoneID = "";
117     napi_valuetype valueType = napi_valuetype::napi_undefined;
118     if (argc > 0) {
119         napi_typeof(env, argv[0], &valueType);
120         if (valueType != napi_valuetype::napi_string) {
121             return nullptr;
122         }
123         int32_t code = 0;
124         zoneID = VariableConvertor::GetString(env, argv[0], code);
125         if (code != 0) {
126             return nullptr;
127         }
128     }
129     if (argc < FUNC_ARGS_COUNT) {
130         return nullptr;
131     }
132     napi_typeof(env, argv[1], &valueType);
133     if (valueType != napi_valuetype::napi_boolean) {
134         return nullptr;
135     }
136     bool isZoneID = false;
137     status = napi_get_value_bool(env, argv[1], &isZoneID);
138     if (status != napi_ok) {
139         return nullptr;
140     }
141     std::unique_ptr<I18nTimeZoneAddon> obj = std::make_unique<I18nTimeZoneAddon>();
142     status =
143         napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), I18nTimeZoneAddon::Destructor, nullptr, nullptr);
144     if (status != napi_ok) {
145         return nullptr;
146     }
147     obj->timezone_ = I18nTimeZone::CreateInstance(zoneID, isZoneID);
148     if (!obj->timezone_) {
149         return nullptr;
150     }
151     obj.release();
152     return thisVar;
153 }
154 
GetAvailableTimezoneIDs(napi_env env,napi_callback_info info)155 napi_value I18nTimeZoneAddon::GetAvailableTimezoneIDs(napi_env env, napi_callback_info info)
156 {
157     I18nErrorCode errorCode = I18nErrorCode::SUCCESS;
158     std::set<std::string> timezoneIDs = I18nTimeZone::GetAvailableIDs(errorCode);
159     if (errorCode != I18nErrorCode::SUCCESS) {
160         return nullptr;
161     }
162     napi_value result = nullptr;
163     napi_status status = napi_create_array_with_length(env, timezoneIDs.size(), &result);
164     if (status != napi_ok) {
165         HILOG_ERROR_I18N("GetAvailableTimezoneIDs: Failed to create array");
166         return nullptr;
167     }
168     size_t index = 0;
169     for (std::set<std::string>::iterator it = timezoneIDs.begin(); it != timezoneIDs.end(); ++it) {
170         napi_value value = nullptr;
171         status = napi_create_string_utf8(env, (*it).c_str(), NAPI_AUTO_LENGTH, &value);
172         if (status != napi_ok) {
173             HILOG_ERROR_I18N("Failed to create string item");
174             return nullptr;
175         }
176         status = napi_set_element(env, result, index, value);
177         if (status != napi_ok) {
178             HILOG_ERROR_I18N("Failed to set array item");
179             return nullptr;
180         }
181         ++index;
182     }
183     return result;
184 }
185 
GetAvailableZoneCityIDs(napi_env env,napi_callback_info info)186 napi_value I18nTimeZoneAddon::GetAvailableZoneCityIDs(napi_env env, napi_callback_info info)
187 {
188     std::set<std::string> cityIDs = I18nTimeZone::GetAvailableZoneCityIDs();
189     napi_value result = nullptr;
190     napi_status status = napi_create_array_with_length(env, cityIDs.size(), &result);
191     if (status != napi_ok) {
192         HILOG_ERROR_I18N("GetAvailableZoneCityIDs: Failed to create array");
193         return nullptr;
194     }
195     size_t index = 0;
196     for (auto it = cityIDs.begin(); it != cityIDs.end(); ++it) {
197         napi_value value = nullptr;
198         status = napi_create_string_utf8(env, (*it).c_str(), NAPI_AUTO_LENGTH, &value);
199         if (status != napi_ok) {
200             HILOG_ERROR_I18N("GetAvailableZoneCityIDs: Failed to create string item");
201             return nullptr;
202         }
203         status = napi_set_element(env, result, index, value);
204         if (status != napi_ok) {
205             HILOG_ERROR_I18N("GetAvailableZoneCityIDs: Failed to set array item");
206             return nullptr;
207         }
208         ++index;
209     }
210     return result;
211 }
212 
GetCityDisplayName(napi_env env,napi_callback_info info)213 napi_value I18nTimeZoneAddon::GetCityDisplayName(napi_env env, napi_callback_info info)
214 {
215     size_t argc = 2;
216     napi_value argv[2] = { 0 };
217     napi_value thisVar = nullptr;
218     void *data = nullptr;
219     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
220     if (status != napi_ok) {
221         return nullptr;
222     }
223     if (argc < FUNC_ARGS_COUNT) {
224         return nullptr;
225     }
226     napi_valuetype valueType = napi_valuetype::napi_undefined;
227     napi_typeof(env, argv[0], &valueType);
228     if (valueType != napi_valuetype::napi_string) {
229         HILOG_ERROR_I18N("GetCityDisplayName: Invalid parameter type");
230         return nullptr;
231     }
232     int32_t code = 0;
233     std::string cityID = VariableConvertor::GetString(env, argv[0], code);
234     if (code != 0) {
235         return nullptr;
236     }
237     std::string locale = VariableConvertor::GetString(env, argv[1], code);
238     if (code != 0) {
239         return nullptr;
240     }
241     std::string name = I18nTimeZone::GetCityDisplayName(cityID, locale);
242     napi_value result = nullptr;
243     status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &result);
244     if (status != napi_ok) {
245         return nullptr;
246     }
247     return result;
248 }
249 
GetTimezoneFromCity(napi_env env,napi_callback_info info)250 napi_value I18nTimeZoneAddon::GetTimezoneFromCity(napi_env env, napi_callback_info info)
251 {
252     size_t argc = 1;
253     napi_value argv[1] = { nullptr };
254     napi_value thisVar = nullptr;
255     void *data = nullptr;
256     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
257     return StaticGetTimeZone(env, argv, false);
258 }
259 
GetTimezonesByLocation(napi_env env,napi_callback_info info)260 napi_value I18nTimeZoneAddon::GetTimezonesByLocation(napi_env env, napi_callback_info info)
261 {
262     size_t argc = 2;
263     napi_value argv[2] = {0, 0};
264     napi_value thisVar = nullptr;
265     void *data = nullptr;
266     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
267     if (status != napi_ok) {
268         return nullptr;
269     }
270     if (argc < FUNC_ARGS_COUNT) {
271         HILOG_ERROR_I18N("GetTimezonesByLocation: Missing parameter");
272         ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "longitude or latitude", "", true);
273         return nullptr;
274     }
275     double x;
276     double y;
277     VariableConvertor::VerifyType(env, "longitude", "number", argv[0]);
278     VariableConvertor::VerifyType(env, "latitude", "number", argv[1]);
279     if (!CheckLongitudeTypeAndScope(env, argv[0], x) ||
280         !CheckLatitudeTypeAndScope(env, argv[1], y)) {
281         ErrorUtil::NapiThrow(env, I18N_NOT_VALID, "longitude or latitude", "a valid value", true);
282         return nullptr;
283     }
284     napi_value timezoneList = nullptr;
285     napi_create_array(env, &timezoneList);
286     std::vector<std::string> tempList = I18nTimeZone::GetTimezoneIdByLocation(x, y);
287     for (size_t i = 0; i < tempList.size(); i++) {
288         napi_value timezoneId = nullptr;
289         status = napi_create_string_utf8(env, tempList[i].c_str(), NAPI_AUTO_LENGTH, &timezoneId);
290         if (status != napi_ok) {
291             return nullptr;
292         }
293         napi_value argTimeZoneId[1] = { timezoneId };
294         napi_value timezone = StaticGetTimeZone(env, argTimeZoneId, true);
295         status = napi_set_element(env, timezoneList, i, timezone);
296         if (status != napi_ok) {
297             return nullptr;
298         }
299     }
300 
301     return timezoneList;
302 }
303 
CheckLongitudeTypeAndScope(napi_env env,napi_value argv,double & x)304 bool I18nTimeZoneAddon::CheckLongitudeTypeAndScope(napi_env env, napi_value argv, double &x)
305 {
306     napi_status status = napi_get_value_double(env, argv, &x);
307     if (status != napi_ok) {
308         HILOG_ERROR_I18N("GetTimezonesByLocation: Parse first argument x failed");
309         return false;
310     }
311     // -180 and 179.9 is the scope of longitude
312     if (x < -180 || x > 179.9) {
313         HILOG_ERROR_I18N("GetTimezonesByLocation: Args x exceed it's scope.");
314         return false;
315     }
316     return true;
317 }
318 
CheckLatitudeTypeAndScope(napi_env env,napi_value argv,double & y)319 bool I18nTimeZoneAddon::CheckLatitudeTypeAndScope(napi_env env, napi_value argv, double &y)
320 {
321     napi_status status = napi_get_value_double(env, argv, &y);
322     if (status != napi_ok) {
323         HILOG_ERROR_I18N("GetTimezonesByLocation: Parse second argument y failed");
324         return false;
325     }
326     // -90 and 89.9 is the scope of latitude
327     if (y < -90 || y > 89.9) {
328         HILOG_ERROR_I18N("GetTimezonesByLocation: Args y exceed it's scope.");
329         return false;
330     }
331     return true;
332 }
333 
GetID(napi_env env,napi_callback_info info)334 napi_value I18nTimeZoneAddon::GetID(napi_env env, napi_callback_info info)
335 {
336     size_t argc = 0;
337     napi_value *argv = nullptr;
338     napi_value thisVar = nullptr;
339     void *data = nullptr;
340     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
341     I18nTimeZoneAddon *obj = nullptr;
342     napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
343     if (status != napi_ok || !obj || !obj->timezone_) {
344         HILOG_ERROR_I18N("GetID: Get TimeZone object failed");
345         return nullptr;
346     }
347     std::string result = obj->timezone_->GetID();
348     napi_value value = nullptr;
349     status = napi_create_string_utf8(env, result.c_str(), NAPI_AUTO_LENGTH, &value);
350     if (status != napi_ok) {
351         HILOG_ERROR_I18N("GetID: Create result failed");
352         return nullptr;
353     }
354     return value;
355 }
356 
GetTimeZoneDisplayName(napi_env env,napi_callback_info info)357 napi_value I18nTimeZoneAddon::GetTimeZoneDisplayName(napi_env env, napi_callback_info info)
358 {
359     size_t argc = 2;
360     napi_value argv[2] = { 0 };
361     napi_value thisVar = nullptr;
362     void *data = nullptr;
363     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
364     if (status != napi_ok) {
365         return nullptr;
366     }
367 
368     I18nTimeZoneAddon *obj = nullptr;
369     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
370     if (status != napi_ok || !obj || !obj->timezone_) {
371         HILOG_ERROR_I18N("GetTimeZoneDisplayName: Get TimeZone object failed");
372         return nullptr;
373     }
374 
375     std::string locale;
376     bool isDST = false;
377     int32_t parameterStatus = GetParameter(env, argv, locale, isDST);
378 
379     std::string result;
380     if (parameterStatus == -1) {  // -1 represents Invalid parameter.
381         HILOG_ERROR_I18N("GetTimeZoneDisplayName: Parameter type does not match");
382         return nullptr;
383     } else if (parameterStatus == 0) {
384         result = obj->timezone_->GetDisplayName();
385     } else if (parameterStatus == 1) {  // 1 represents one string parameter.
386         result = obj->timezone_->GetDisplayName(locale);
387     } else if (parameterStatus == 2) {  // 2 represents one boolean parameter.
388         result = obj->timezone_->GetDisplayName(isDST);
389     } else {
390         result = obj->timezone_->GetDisplayName(locale, isDST);
391     }
392 
393     napi_value value = nullptr;
394     status = napi_create_string_utf8(env, result.c_str(), NAPI_AUTO_LENGTH, &value);
395     if (status != napi_ok) {
396         HILOG_ERROR_I18N("GetTimeZoneDisplayName: Create result failed");
397         return nullptr;
398     }
399     return value;
400 }
401 
GetRawOffset(napi_env env,napi_callback_info info)402 napi_value I18nTimeZoneAddon::GetRawOffset(napi_env env, napi_callback_info info)
403 {
404     size_t argc = 0;
405     napi_value *argv = nullptr;
406     napi_value thisVar = nullptr;
407     void *data = nullptr;
408     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
409     I18nTimeZoneAddon *obj = nullptr;
410     napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
411     if (status != napi_ok || !obj || !obj->timezone_) {
412         HILOG_ERROR_I18N("GetRawOffset: Get TimeZone object failed");
413         return nullptr;
414     }
415     int32_t result = obj->timezone_->GetRawOffset();
416     napi_value value = nullptr;
417     status = napi_create_int32(env, result, &value);
418     if (status != napi_ok) {
419         HILOG_ERROR_I18N("GetRawOffset: Create result failed");
420         return nullptr;
421     }
422     return value;
423 }
424 
GetOffset(napi_env env,napi_callback_info info)425 napi_value I18nTimeZoneAddon::GetOffset(napi_env env, napi_callback_info info)
426 {
427     size_t argc = 1;
428     napi_value argv[1] = { 0 };
429     napi_value thisVar = nullptr;
430     void *data = nullptr;
431     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
432     if (status != napi_ok) {
433         return nullptr;
434     }
435 
436     double date = 0;
437     if (VariableConvertor::CheckNapiValueType(env, argv[0])) {
438         napi_valuetype valueType = napi_valuetype::napi_undefined;
439         napi_typeof(env, argv[0], &valueType);
440         if (valueType != napi_valuetype::napi_number) {
441             HILOG_ERROR_I18N("GetOffset: Invalid parameter type");
442             return nullptr;
443         }
444         status = napi_get_value_double(env, argv[0], &date);
445         if (status != napi_ok) {
446             HILOG_ERROR_I18N("Get parameter date failed");
447             return nullptr;
448         }
449     } else {
450         auto time = std::chrono::system_clock::now();
451         auto since_epoch = time.time_since_epoch();
452         auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(since_epoch);
453         date = (double)millis.count();
454     }
455 
456     I18nTimeZoneAddon *obj = nullptr;
457     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
458     if (status != napi_ok || !obj || !obj->timezone_) {
459         HILOG_ERROR_I18N("GetOffset: Get TimeZone object failed");
460         return nullptr;
461     }
462     int32_t result = obj->timezone_->GetOffset(date);
463     napi_value value = nullptr;
464     status = napi_create_int32(env, result, &value);
465     if (status != napi_ok) {
466         HILOG_ERROR_I18N("GetOffset: Create result failed");
467         return nullptr;
468     }
469     return value;
470 }
471 
StaticGetTimeZone(napi_env env,napi_value * argv,bool isZoneID)472 napi_value I18nTimeZoneAddon::StaticGetTimeZone(napi_env env, napi_value *argv, bool isZoneID)
473 {
474     napi_value constructor = nullptr;
475     napi_status status = napi_get_reference_value(env, *g_timezoneConstructor, &constructor);
476     if (status != napi_ok) {
477         HILOG_ERROR_I18N("Failed to create reference at StaticGetTimeZone");
478         return nullptr;
479     }
480     napi_value newArgv[2] = { 0 };
481     newArgv[0] = argv[0];
482     status = napi_get_boolean(env, isZoneID, &newArgv[1]);
483     if (status != napi_ok) {
484         return nullptr;
485     }
486     napi_value result = nullptr;
487     status = napi_new_instance(env, constructor, 2, newArgv, &result); // 2 is parameter num
488     if (status != napi_ok) {
489         HILOG_ERROR_I18N("StaticGetTimeZone create instance failed");
490         return nullptr;
491     }
492     return result;
493 }
494 
GetParameter(napi_env env,napi_value * argv,std::string & localeStr,bool & isDST)495 int32_t I18nTimeZoneAddon::GetParameter(napi_env env, napi_value *argv, std::string &localeStr, bool &isDST)
496 {
497     napi_status status = napi_ok;
498     if (VariableConvertor::CheckNapiValueType(env, argv[1])) {
499         napi_valuetype valueType0 = napi_valuetype::napi_undefined;
500         napi_valuetype valueType1 = napi_valuetype::napi_undefined;
501         napi_typeof(env, argv[0], &valueType0);  // 0 represents first parameter
502         napi_typeof(env, argv[1], &valueType1);  // 1 represents second parameter
503         bool firstParamFlag = VariableConvertor::CheckNapiValueType(env, argv[0]);
504         if (valueType1 == napi_valuetype::napi_boolean) {
505             status = napi_get_value_bool(env, argv[1], &isDST);
506             if (status != napi_ok) {
507                 return -1;  // -1 represents Invalid parameter.
508             } else if (!firstParamFlag) {
509                 return 2;  // 2 represents one boolean parameter.
510             }
511             if (valueType0 == napi_valuetype::napi_string &&
512                  GetStringFromJS(env, argv[0], localeStr)) {
513                 return 3;  // 3 represents one string parameter and one bool parameter.
514             }
515         }
516         return -1;  // -1 represents Invalid parameter.
517     }
518     return GetFirstParameter(env, argv[0], localeStr, isDST);
519 }
520 
GetStringFromJS(napi_env env,napi_value argv,std::string & jsString)521 bool I18nTimeZoneAddon::GetStringFromJS(napi_env env, napi_value argv, std::string &jsString)
522 {
523     size_t len = 0;
524     napi_status status = napi_get_value_string_utf8(env, argv, nullptr, 0, &len);
525     if (status != napi_ok) {
526         HILOG_ERROR_I18N("Failed to get string length");
527         return false;
528     }
529     std::vector<char> argvBuf(len + 1);
530     status = napi_get_value_string_utf8(env, argv, argvBuf.data(), len + 1, &len);
531     if (status != napi_ok) {
532         HILOG_ERROR_I18N("Failed to get string item");
533         return false;
534     }
535     jsString = argvBuf.data();
536     return true;
537 }
538 
GetFirstParameter(napi_env env,napi_value value,std::string & localeStr,bool & isDST)539 int32_t I18nTimeZoneAddon::GetFirstParameter(napi_env env, napi_value value, std::string &localeStr, bool &isDST)
540 {
541     if (!VariableConvertor::CheckNapiValueType(env, value)) {
542         return 0;  // 0 represents no parameter.
543     } else {
544         napi_status status = napi_ok;
545         napi_valuetype valueType = napi_valuetype::napi_undefined;
546         napi_typeof(env, value, &valueType);
547         if (valueType == napi_valuetype::napi_string) {
548             bool valid = GetStringFromJS(env, value, localeStr);
549             // -1 represents Invalid parameter.
550             // 1 represents one string parameter.
551             return !valid ? -1 : 1;
552         } else if (valueType == napi_valuetype::napi_boolean) {
553             status = napi_get_value_bool(env, value, &isDST);
554             // -1 represents Invalid parameter.
555             // 2 represents one boolean parameter.
556             return (status != napi_ok) ? -1 : 2;
557         }
558         return -1;  // -1 represents Invalid parameter.
559     }
560 }
561 } // namespace I18n
562 } // namespace Global
563 } // namespace OHOS