• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 
16 #include "napi_system_date_time.h"
17 
18 #include "parameters.h"
19 #include "napi_work.h"
20 #include "napi_utils.h"
21 #include "time_hilog.h"
22 #include "time_service_client.h"
23 
24 using namespace OHOS::MiscServices;
25 
26 namespace OHOS {
27 namespace MiscServices {
28 namespace Time {
29 
30 constexpr int64_t SECONDS_TO_NANO = 1000000000;
31 constexpr int64_t SECONDS_TO_MILLI = 1000;
32 constexpr int64_t NANO_TO_MILLI = SECONDS_TO_NANO / SECONDS_TO_MILLI;
33 constexpr int32_t STARTUP = 0;
34 constexpr int32_t ACTIVE = 1;
35 const std::string TIMEZONE_KEY = "persist.time.timezone";
36 
SystemDateTimeInit(napi_env env,napi_value exports)37 napi_value NapiSystemDateTime::SystemDateTimeInit(napi_env env, napi_value exports)
38 {
39     napi_value timeType = nullptr;
40     napi_value startup = nullptr;
41     napi_value active = nullptr;
42     NAPI_CALL(env, napi_create_int32(env, STARTUP, &startup));
43     NAPI_CALL(env, napi_create_int32(env, ACTIVE, &active));
44     NAPI_CALL(env, napi_create_object(env, &timeType));
45     NAPI_CALL(env, napi_set_named_property(env, timeType, "STARTUP", startup));
46     NAPI_CALL(env, napi_set_named_property(env, timeType, "ACTIVE", active));
47 
48     napi_property_descriptor descriptors[] = {
49         DECLARE_NAPI_STATIC_FUNCTION("setTime", SetTime),
50         DECLARE_NAPI_STATIC_FUNCTION("getCurrentTime", GetCurrentTime),
51         DECLARE_NAPI_STATIC_FUNCTION("getRealActiveTime", GetRealActiveTime),
52         DECLARE_NAPI_STATIC_FUNCTION("getRealTime", GetRealTime),
53         DECLARE_NAPI_STATIC_FUNCTION("getTime", GetTime),
54         DECLARE_NAPI_STATIC_FUNCTION("setDate", SetDate),
55         DECLARE_NAPI_STATIC_FUNCTION("getDate", GetDate),
56         DECLARE_NAPI_STATIC_FUNCTION("setTimezone", SetTimezone),
57         DECLARE_NAPI_STATIC_FUNCTION("getTimezone", GetTimezone),
58         DECLARE_NAPI_STATIC_FUNCTION("getUptime", GetUptime),
59         DECLARE_NAPI_STATIC_FUNCTION("getTimezoneSync", GetTimezoneSync),
60         DECLARE_NAPI_STATIC_PROPERTY("TimeType", timeType),
61     };
62 
63     napi_status status =
64         napi_define_properties(env, exports, sizeof(descriptors) / sizeof(napi_property_descriptor), descriptors);
65     if (status != napi_ok) {
66         TIME_HILOGE(TIME_MODULE_JS_NAPI, "define manager properties failed");
67         return NapiUtils::GetUndefinedValue(env);
68     }
69     return exports;
70 }
71 
SetTime(napi_env env,napi_callback_info info)72 napi_value NapiSystemDateTime::SetTime(napi_env env, napi_callback_info info)
73 {
74     struct SetTimeContext : public ContextBase {
75         int64_t time = 0;
76     };
77     auto *setTimeContext = new SetTimeContext();
78     auto inputParser = [env, setTimeContext](size_t argc, napi_value *argv) {
79         CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, setTimeContext, argc >= ARGC_ONE, "invalid arguments",
80             JsErrorCode::PARAMETER_ERROR);
81         setTimeContext->status = napi_get_value_int64(env, argv[ARGV_FIRST], &setTimeContext->time);
82         CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, setTimeContext, setTimeContext->status == napi_ok, "invalid time",
83             JsErrorCode::PARAMETER_ERROR);
84         setTimeContext->status = napi_ok;
85     };
86     setTimeContext->GetCbInfo(env, info, inputParser);
87     auto executor = [setTimeContext]() {
88         auto innerCode = TimeServiceClient::GetInstance()->SetTimeV9(setTimeContext->time);
89         if (innerCode != JsErrorCode::ERROR_OK) {
90             setTimeContext->errCode = innerCode;
91             setTimeContext->status = napi_generic_failure;
92         }
93     };
94     auto complete = [env](napi_value &output) { output = NapiUtils::GetUndefinedValue(env); };
95     return NapiWork::AsyncEnqueue(env, setTimeContext, "SetTime", executor, complete);
96 }
97 
SetDate(napi_env env,napi_callback_info info)98 napi_value NapiSystemDateTime::SetDate(napi_env env, napi_callback_info info)
99 {
100     struct SetDateContext : public ContextBase {
101         int64_t time = 0;
102     };
103     auto *setDateContext = new SetDateContext();
104     auto inputParser = [env, setDateContext](size_t argc, napi_value *argv) {
105         CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, setDateContext, argc >= ARGC_ONE, "invalid arguments",
106             JsErrorCode::PARAMETER_ERROR);
107         napi_valuetype valueType = napi_undefined;
108         napi_typeof(env, argv[ARGV_FIRST], &valueType);
109         if (valueType == napi_number) {
110             napi_get_value_int64(env, argv[ARGV_FIRST], &setDateContext->time);
111             CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, setDateContext, setDateContext->time >= 0, "invalid time",
112                 JsErrorCode::PARAMETER_ERROR);
113         } else {
114             bool hasProperty = false;
115             napi_valuetype resValueType = napi_undefined;
116             napi_has_named_property(env, argv[ARGV_FIRST], "getTime", &hasProperty);
117             CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, setDateContext, hasProperty, "getTime failed",
118                 JsErrorCode::PARAMETER_ERROR);
119             napi_value getTimeFunc = nullptr;
120             napi_get_named_property(env, argv[0], "getTime", &getTimeFunc);
121             napi_value getTimeResult = nullptr;
122             napi_call_function(env, argv[0], getTimeFunc, 0, nullptr, &getTimeResult);
123             napi_typeof(env, getTimeResult, &resValueType);
124             CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, setDateContext, resValueType == napi_number, "type mismatch",
125                 JsErrorCode::PARAMETER_ERROR);
126             setDateContext->status = napi_get_value_int64(env, getTimeResult, &setDateContext->time);
127         }
128         CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, setDateContext, setDateContext->status == napi_ok, "invalid time",
129             JsErrorCode::PARAMETER_ERROR);
130         setDateContext->status = napi_ok;
131     };
132     setDateContext->GetCbInfo(env, info, inputParser);
133     auto executor = [setDateContext]() {
134         auto innerCode = TimeServiceClient::GetInstance()->SetTimeV9(setDateContext->time);
135         if (innerCode != JsErrorCode::ERROR_OK) {
136             setDateContext->errCode = innerCode;
137             setDateContext->status = napi_generic_failure;
138         }
139     };
140     auto complete = [env](napi_value &output) { output = NapiUtils::GetUndefinedValue(env); };
141     return NapiWork::AsyncEnqueue(env, setDateContext, "SetDate", executor, complete);
142 }
143 
GetRealActiveTime(napi_env env,napi_callback_info info)144 napi_value NapiSystemDateTime::GetRealActiveTime(napi_env env, napi_callback_info info)
145 {
146     struct GetRealActiveTimeContext : public ContextBase {
147         int64_t time = 0;
148         bool isNano = false;
149     };
150     auto *getRealActiveTimeContext = new GetRealActiveTimeContext();
151     auto inputParser = [env, getRealActiveTimeContext](size_t argc, napi_value *argv) {
152         if (argc >= ARGC_ONE) {
153             napi_valuetype valueType = napi_undefined;
154             napi_typeof(env, argv[ARGV_FIRST], &valueType);
155             if (valueType == napi_boolean) {
156                 getRealActiveTimeContext->status =
157                     napi_get_value_bool(env, argv[ARGV_FIRST], &getRealActiveTimeContext->isNano);
158                 CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, getRealActiveTimeContext,
159                     getRealActiveTimeContext->status == napi_ok, "invalid isNano", JsErrorCode::PARAMETER_ERROR);
160             }
161         }
162         getRealActiveTimeContext->status = napi_ok;
163     };
164     getRealActiveTimeContext->GetCbInfo(env, info, inputParser);
165     auto executor = [getRealActiveTimeContext]() {
166         int32_t innerCode;
167         if (getRealActiveTimeContext->isNano) {
168             innerCode = TimeServiceClient::GetInstance()->GetMonotonicTimeNs(getRealActiveTimeContext->time);
169         } else {
170             innerCode = TimeServiceClient::GetInstance()->GetMonotonicTimeMs(getRealActiveTimeContext->time);
171         }
172         if (innerCode != JsErrorCode::ERROR_OK) {
173             getRealActiveTimeContext->errCode = NapiUtils::ConvertErrorCode(innerCode);
174             getRealActiveTimeContext->status = napi_generic_failure;
175         }
176     };
177     auto complete = [env, getRealActiveTimeContext](napi_value &output) {
178         getRealActiveTimeContext->status = napi_create_int64(env, getRealActiveTimeContext->time, &output);
179         CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, getRealActiveTimeContext,
180             "convert native object to javascript object failed", JsErrorCode::ERROR);
181     };
182     return NapiWork::AsyncEnqueue(env, getRealActiveTimeContext, "GetRealActiveTime", executor, complete);
183 }
184 
GetCurrentTime(napi_env env,napi_callback_info info)185 napi_value NapiSystemDateTime::GetCurrentTime(napi_env env, napi_callback_info info)
186 {
187     struct GetCurrentTimeContext : public ContextBase {
188         int64_t time = 0;
189         bool isNano = false;
190     };
191     auto *getCurrentTimeContext = new GetCurrentTimeContext();
192     auto inputParser = [env, getCurrentTimeContext](size_t argc, napi_value *argv) {
193         if (argc >= ARGC_ONE) {
194             napi_valuetype valueType = napi_undefined;
195             napi_typeof(env, argv[ARGV_FIRST], &valueType);
196             if (valueType == napi_boolean) {
197                 getCurrentTimeContext->status =
198                     napi_get_value_bool(env, argv[ARGV_FIRST], &getCurrentTimeContext->isNano);
199                 CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, getCurrentTimeContext,
200                     getCurrentTimeContext->status == napi_ok, "invalid isNano", JsErrorCode::PARAMETER_ERROR);
201             }
202         }
203         getCurrentTimeContext->status = napi_ok;
204     };
205     getCurrentTimeContext->GetCbInfo(env, info, inputParser);
206     auto executor = [getCurrentTimeContext]() {
207         int32_t innerCode;
208         if (getCurrentTimeContext->isNano) {
209             innerCode = TimeServiceClient::GetInstance()->GetWallTimeNs(getCurrentTimeContext->time);
210         } else {
211             innerCode = TimeServiceClient::GetInstance()->GetWallTimeMs(getCurrentTimeContext->time);
212         }
213         if (innerCode != JsErrorCode::ERROR_OK) {
214             getCurrentTimeContext->errCode = innerCode;
215             getCurrentTimeContext->status = napi_generic_failure;
216         }
217     };
218     auto complete = [getCurrentTimeContext, env](napi_value &output) {
219         getCurrentTimeContext->status = napi_create_int64(env, getCurrentTimeContext->time, &output);
220         CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, getCurrentTimeContext,
221             "convert native object to javascript object failed", JsErrorCode::ERROR);
222     };
223     return NapiWork::AsyncEnqueue(env, getCurrentTimeContext, "GetCurrentTime", executor, complete);
224 }
225 
GetTime(napi_env env,napi_callback_info info)226 napi_value NapiSystemDateTime::GetTime(napi_env env, napi_callback_info info)
227 {
228     struct GetTimeContext : public ContextBase {
229         int64_t time = 0;
230         bool isNano = false;
231     };
232     auto *getTimeContext = new GetTimeContext();
233     auto inputParser = [env, getTimeContext](size_t argc, napi_value *argv) {
234         if (argc >= ARGC_ONE) {
235             napi_valuetype valueType = napi_undefined;
236             napi_typeof(env, argv[ARGV_FIRST], &valueType);
237             if (valueType == napi_boolean) {
238                 getTimeContext->status = napi_get_value_bool(env, argv[ARGV_FIRST], &getTimeContext->isNano);
239                 CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, getTimeContext, getTimeContext->status == napi_ok,
240                                        "invalid isNano", JsErrorCode::PARAMETER_ERROR);
241             }
242         }
243         getTimeContext->status = napi_ok;
244     };
245     getTimeContext->GetCbInfo(env, info, inputParser, true);
246     auto executor = [getTimeContext]() {
247         int32_t innerCode = GetDeviceTime(CLOCK_REALTIME, getTimeContext->isNano, getTimeContext->time);
248         if (innerCode != JsErrorCode::ERROR_OK) {
249             getTimeContext->errCode = innerCode;
250             getTimeContext->status = napi_generic_failure;
251         }
252     };
253     auto complete = [getTimeContext](napi_value &output) {
254         getTimeContext->status = napi_create_int64(getTimeContext->env, getTimeContext->time, &output);
255         CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, getTimeContext,
256                                  "convert native object to javascript object failed", JsErrorCode::ERROR);
257     };
258     return NapiWork::SyncEnqueue(env, getTimeContext, "GetTime", executor, complete);
259 }
260 
GetRealTime(napi_env env,napi_callback_info info)261 napi_value NapiSystemDateTime::GetRealTime(napi_env env, napi_callback_info info)
262 {
263     struct GetRealTimeContext : public ContextBase {
264         int64_t time = 0;
265         bool isNano = false;
266     };
267     auto *getRealTimeContext = new GetRealTimeContext();
268     auto inputParser = [env, getRealTimeContext](size_t argc, napi_value *argv) {
269         if (argc >= ARGC_ONE) {
270             napi_valuetype valueType = napi_undefined;
271             napi_typeof(env, argv[ARGV_FIRST], &valueType);
272             if (valueType == napi_boolean) {
273                 getRealTimeContext->status = napi_get_value_bool(env, argv[ARGV_FIRST], &getRealTimeContext->isNano);
274                 CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, getRealTimeContext, getRealTimeContext->status == napi_ok,
275                     "invalid isNano", JsErrorCode::PARAMETER_ERROR);
276             }
277         }
278         getRealTimeContext->status = napi_ok;
279     };
280     getRealTimeContext->GetCbInfo(env, info, inputParser);
281     auto executor = [getRealTimeContext]() {
282         int32_t innerCode;
283         if (getRealTimeContext->isNano) {
284             innerCode = TimeServiceClient::GetInstance()->GetBootTimeNs(getRealTimeContext->time);
285         } else {
286             innerCode = TimeServiceClient::GetInstance()->GetBootTimeMs(getRealTimeContext->time);
287         }
288         if (innerCode != JsErrorCode::ERROR_OK) {
289             getRealTimeContext->errCode = innerCode;
290             getRealTimeContext->status = napi_generic_failure;
291         }
292     };
293     auto complete = [getRealTimeContext](napi_value &output) {
294         getRealTimeContext->status = napi_create_int64(getRealTimeContext->env, getRealTimeContext->time, &output);
295         CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, getRealTimeContext,
296             "convert native object to javascript object failed", JsErrorCode::ERROR);
297     };
298     return NapiWork::AsyncEnqueue(env, getRealTimeContext, "GetRealTime", executor, complete);
299 }
300 
GetUptime(napi_env env,napi_callback_info info)301 napi_value NapiSystemDateTime::GetUptime(napi_env env, napi_callback_info info)
302 {
303     struct GetUpTimeContext : public ContextBase {
304         int64_t time = 0;
305         int32_t timeType = STARTUP;
306         bool isNanoseconds = false;
307     };
308     auto *getUpTimeContext = new GetUpTimeContext();
309     auto inputParser = [env, getUpTimeContext](size_t argc, napi_value *argv) {
310         getUpTimeContext->status = napi_get_value_int32(env, argv[ARGV_FIRST], &getUpTimeContext->timeType);
311         CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, getUpTimeContext, getUpTimeContext->status == napi_ok,
312                                "invalid timeType", JsErrorCode::PARAMETER_ERROR);
313         CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, getUpTimeContext,
314             (getUpTimeContext->timeType >= STARTUP && getUpTimeContext->timeType <= ACTIVE), "invalid timeType",
315             JsErrorCode::PARAMETER_ERROR);
316         if (argc >= ARGC_TWO) {
317             napi_valuetype valueType = napi_undefined;
318             napi_typeof(env, argv[ARGV_SECOND], &valueType);
319             if (valueType == napi_boolean) {
320                 getUpTimeContext->status =
321                     napi_get_value_bool(env, argv[ARGV_SECOND], &getUpTimeContext->isNanoseconds);
322                 CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, getUpTimeContext, getUpTimeContext->status == napi_ok,
323                     "get isNanoseconds failed", JsErrorCode::PARAMETER_ERROR);
324             }
325         }
326         getUpTimeContext->status = napi_ok;
327     };
328     getUpTimeContext->GetCbInfo(env, info, inputParser, true);
329     auto executor = [getUpTimeContext]() {
330         int32_t innerCode;
331         if (getUpTimeContext->timeType == STARTUP) {
332             innerCode = GetDeviceTime(CLOCK_BOOTTIME, getUpTimeContext->isNanoseconds, getUpTimeContext->time);
333         } else {
334             innerCode = GetDeviceTime(CLOCK_MONOTONIC, getUpTimeContext->isNanoseconds, getUpTimeContext->time);
335         }
336         if (innerCode != JsErrorCode::ERROR_OK) {
337             getUpTimeContext->errCode = innerCode;
338             getUpTimeContext->status = napi_generic_failure;
339         }
340     };
341     auto complete = [getUpTimeContext](napi_value &output) {
342         getUpTimeContext->status = napi_create_int64(getUpTimeContext->env, getUpTimeContext->time, &output);
343         CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, getUpTimeContext,
344                                  "convert native object to javascript object failed", JsErrorCode::ERROR);
345     };
346     return NapiWork::SyncEnqueue(env, getUpTimeContext, "GetUpTime", executor, complete);
347 }
348 
GetDate(napi_env env,napi_callback_info info)349 napi_value NapiSystemDateTime::GetDate(napi_env env, napi_callback_info info)
350 {
351     struct GetDateContext : public ContextBase {
352         int64_t time = 0;
353     };
354     auto *getDateContext = new GetDateContext();
355     auto inputParser = [getDateContext](size_t argc, napi_value *argv) { getDateContext->status = napi_ok; };
356     getDateContext->GetCbInfo(env, info, inputParser);
357     auto executor = [getDateContext]() {
358         auto innerCode = TimeServiceClient::GetInstance()->GetWallTimeMs(getDateContext->time);
359         if (innerCode != JsErrorCode::ERROR_OK) {
360             getDateContext->errCode = innerCode;
361             getDateContext->status = napi_generic_failure;
362         }
363     };
364     auto complete = [env, getDateContext](napi_value &output) {
365         getDateContext->status = napi_create_date(env, getDateContext->time, &output);
366         CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, getDateContext,
367             "convert native object to javascript object failed", JsErrorCode::ERROR);
368     };
369 
370     return NapiWork::AsyncEnqueue(env, getDateContext, "GetDate", executor, complete);
371 }
372 
SetTimezone(napi_env env,napi_callback_info info)373 napi_value NapiSystemDateTime::SetTimezone(napi_env env, napi_callback_info info)
374 {
375     struct SetTimezoneContext : public ContextBase {
376         std::string timezone;
377     };
378     auto *setTimezoneContext = new SetTimezoneContext();
379     auto inputParser = [env, setTimezoneContext](size_t argc, napi_value *argv) {
380         CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, setTimezoneContext, argc >= ARGC_ONE, "invalid arguments",
381             JsErrorCode::PARAMETER_ERROR);
382         setTimezoneContext->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], setTimezoneContext->timezone);
383         CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, setTimezoneContext, setTimezoneContext->status == napi_ok,
384             "invalid timezone", JsErrorCode::PARAMETER_ERROR);
385         setTimezoneContext->status = napi_ok;
386     };
387     setTimezoneContext->GetCbInfo(env, info, inputParser);
388     auto executor = [setTimezoneContext]() {
389         auto innerCode = TimeServiceClient::GetInstance()->SetTimeZoneV9(setTimezoneContext->timezone);
390         if (innerCode != JsErrorCode::ERROR_OK) {
391             setTimezoneContext->errCode = innerCode;
392             setTimezoneContext->status = napi_generic_failure;
393         }
394     };
395     auto complete = [env](napi_value &output) { output = NapiUtils::GetUndefinedValue(env); };
396     return NapiWork::AsyncEnqueue(env, setTimezoneContext, "SetTimezone", executor, complete);
397 }
398 
GetTimezone(napi_env env,napi_callback_info info)399 napi_value NapiSystemDateTime::GetTimezone(napi_env env, napi_callback_info info)
400 {
401     struct GetTimezoneContext : public ContextBase {
402         std::string timezone;
403     };
404     auto *getTimezoneContext = new GetTimezoneContext();
405     auto inputParser = [getTimezoneContext](size_t argc, napi_value *argv) {
406         getTimezoneContext->status = napi_ok;
407     };
408     getTimezoneContext->GetCbInfo(env, info, inputParser);
409 
410     auto executor = [getTimezoneContext]() {
411         auto innerCode = TimeServiceClient::GetInstance()->GetTimeZone(getTimezoneContext->timezone);
412         if (innerCode != JsErrorCode::ERROR_OK) {
413             getTimezoneContext->errCode = innerCode;
414             getTimezoneContext->status = napi_generic_failure;
415         }
416     };
417     auto complete = [env, getTimezoneContext](napi_value &output) {
418         getTimezoneContext->status = napi_create_string_utf8(env, getTimezoneContext->timezone.c_str(),
419             getTimezoneContext->timezone.size(), &output);
420         TIME_HILOGI(TIME_MODULE_JS_NAPI, "%{public}s, ", getTimezoneContext->timezone.c_str());
421         CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, getTimezoneContext,
422             "convert native object to javascript object failed", JsErrorCode::ERROR);
423     };
424     return NapiWork::AsyncEnqueue(env, getTimezoneContext, "GetTimezone", executor, complete);
425 }
426 
GetTimezoneSync(napi_env env,napi_callback_info info)427 napi_value NapiSystemDateTime::GetTimezoneSync(napi_env env, napi_callback_info info)
428 {
429     struct GetTimezoneContext : public ContextBase {
430         std::string timezone;
431     };
432     auto *getTimezoneContext = new GetTimezoneContext();
433     auto inputParser = [getTimezoneContext](size_t argc, napi_value *argv) { getTimezoneContext->status = napi_ok; };
434     getTimezoneContext->GetCbInfo(env, info, inputParser, true);
435 
436     auto executor = [getTimezoneContext]() {
437         auto innerCode = GetTimezone(getTimezoneContext->timezone);
438         if (innerCode != JsErrorCode::ERROR_OK) {
439             getTimezoneContext->errCode = innerCode;
440             getTimezoneContext->status = napi_generic_failure;
441         }
442     };
443     auto complete = [env, getTimezoneContext](napi_value &output) {
444         getTimezoneContext->status = napi_create_string_utf8(env, getTimezoneContext->timezone.c_str(),
445             getTimezoneContext->timezone.size(), &output);
446         TIME_HILOGI(TIME_MODULE_JS_NAPI, "current timezone %{public}s, ", getTimezoneContext->timezone.c_str());
447         CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, getTimezoneContext,
448             "convert native object to javascript object failed", JsErrorCode::ERROR);
449     };
450     return NapiWork::SyncEnqueue(env, getTimezoneContext, "GetTimezone", executor, complete);
451 }
452 
GetDeviceTime(clockid_t clockId,bool isNano,int64_t & time)453 int32_t NapiSystemDateTime::GetDeviceTime(clockid_t clockId, bool isNano, int64_t &time)
454 {
455     struct timespec tv {};
456     if (clock_gettime(clockId, &tv) < 0) {
457         TIME_HILOGE(TIME_MODULE_SERVICE, "failed clock_gettime, errno: %{public}s", strerror(errno));
458         return ERROR;
459     }
460 
461     if (isNano) {
462         time = tv.tv_sec * SECONDS_TO_NANO + tv.tv_nsec;
463     } else {
464         time = tv.tv_sec * SECONDS_TO_MILLI + tv.tv_nsec / NANO_TO_MILLI;
465     }
466     return ERROR_OK;
467 }
468 
GetTimezone(std::string & timezone)469 int32_t NapiSystemDateTime::GetTimezone(std::string &timezone)
470 {
471     timezone = system::GetParameter(TIMEZONE_KEY, "Asia/Shanghai");
472     if (timezone.empty()) {
473         TIME_HILOGW(TIME_MODULE_SERVICE, "No found timezone from system parameter.");
474         return ERROR;
475     }
476     return ERROR_OK;
477 }
478 } // namespace Time
479 } // namespace MiscServices
480 } // namespace OHOS