• 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, status=%{public}d", status);
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,
80             "Mandatory parameters are left unspecified", 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,
83             "The type of 'time' must be number", 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,
106             "Mandatory parameters are left unspecified", 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,
112                 "date number must >= 0", 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,
118                 "The type of 'date' must be Date", 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,
125                 "The type of 'date' must be Date", 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,
129             "The type of 'date' must be Date", 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         CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, getUpTimeContext, argc >= ARGC_ONE,
311             "Mandatory parameters are left unspecified", JsErrorCode::PARAMETER_ERROR);
312         getUpTimeContext->status = napi_get_value_int32(env, argv[ARGV_FIRST], &getUpTimeContext->timeType);
313         CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, getUpTimeContext, getUpTimeContext->status == napi_ok,
314             "The type of 'timeType' must be number or enum", JsErrorCode::PARAMETER_ERROR);
315         CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, getUpTimeContext,
316             (getUpTimeContext->timeType >= STARTUP && getUpTimeContext->timeType <= ACTIVE),
317             "The 'timeType' must be 'STARTUP' or 'ACTIVE' or 0 or 1", JsErrorCode::PARAMETER_ERROR);
318         if (argc >= ARGC_TWO) {
319             napi_valuetype valueType = napi_undefined;
320             napi_typeof(env, argv[ARGV_SECOND], &valueType);
321             if (valueType == napi_boolean) {
322                 getUpTimeContext->status =
323                     napi_get_value_bool(env, argv[ARGV_SECOND], &getUpTimeContext->isNanoseconds);
324                 CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, getUpTimeContext, getUpTimeContext->status == napi_ok,
325                     "get isNanoseconds failed", JsErrorCode::PARAMETER_ERROR);
326             }
327         }
328         getUpTimeContext->status = napi_ok;
329     };
330     getUpTimeContext->GetCbInfo(env, info, inputParser, true);
331     auto executor = [getUpTimeContext]() {
332         int32_t innerCode;
333         if (getUpTimeContext->timeType == STARTUP) {
334             innerCode = GetDeviceTime(CLOCK_BOOTTIME, getUpTimeContext->isNanoseconds, getUpTimeContext->time);
335         } else {
336             innerCode = GetDeviceTime(CLOCK_MONOTONIC, getUpTimeContext->isNanoseconds, getUpTimeContext->time);
337         }
338         if (innerCode != JsErrorCode::ERROR_OK) {
339             getUpTimeContext->errCode = innerCode;
340             getUpTimeContext->status = napi_generic_failure;
341         }
342     };
343     auto complete = [getUpTimeContext](napi_value &output) {
344         getUpTimeContext->status = napi_create_int64(getUpTimeContext->env, getUpTimeContext->time, &output);
345         CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, getUpTimeContext,
346                                  "convert native object to javascript object failed", JsErrorCode::ERROR);
347     };
348     return NapiWork::SyncEnqueue(env, getUpTimeContext, "GetUpTime", executor, complete);
349 }
350 
GetDate(napi_env env,napi_callback_info info)351 napi_value NapiSystemDateTime::GetDate(napi_env env, napi_callback_info info)
352 {
353     struct GetDateContext : public ContextBase {
354         int64_t time = 0;
355     };
356     auto *getDateContext = new GetDateContext();
357     auto inputParser = [getDateContext](size_t argc, napi_value *argv) { getDateContext->status = napi_ok; };
358     getDateContext->GetCbInfo(env, info, inputParser);
359     auto executor = [getDateContext]() {
360         auto innerCode = TimeServiceClient::GetInstance()->GetWallTimeMs(getDateContext->time);
361         if (innerCode != JsErrorCode::ERROR_OK) {
362             getDateContext->errCode = innerCode;
363             getDateContext->status = napi_generic_failure;
364         }
365     };
366     auto complete = [env, getDateContext](napi_value &output) {
367         getDateContext->status = napi_create_date(env, getDateContext->time, &output);
368         CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, getDateContext,
369             "convert native object to javascript object failed", JsErrorCode::ERROR);
370     };
371 
372     return NapiWork::AsyncEnqueue(env, getDateContext, "GetDate", executor, complete);
373 }
374 
SetTimezone(napi_env env,napi_callback_info info)375 napi_value NapiSystemDateTime::SetTimezone(napi_env env, napi_callback_info info)
376 {
377     struct SetTimezoneContext : public ContextBase {
378         std::string timezone;
379     };
380     auto *setTimezoneContext = new SetTimezoneContext();
381     auto inputParser = [env, setTimezoneContext](size_t argc, napi_value *argv) {
382         CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, setTimezoneContext, argc >= ARGC_ONE,
383             "Mandatory parameters are left unspecified", JsErrorCode::PARAMETER_ERROR);
384         setTimezoneContext->status = NapiUtils::GetValue(env, argv[ARGV_FIRST], setTimezoneContext->timezone);
385         CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, setTimezoneContext, setTimezoneContext->status == napi_ok,
386             "The type of 'timezone' must be string", JsErrorCode::PARAMETER_ERROR);
387         setTimezoneContext->status = napi_ok;
388     };
389     setTimezoneContext->GetCbInfo(env, info, inputParser);
390     auto executor = [setTimezoneContext]() {
391         auto innerCode = TimeServiceClient::GetInstance()->SetTimeZoneV9(setTimezoneContext->timezone);
392         if (innerCode != JsErrorCode::ERROR_OK) {
393             setTimezoneContext->errCode = innerCode;
394             setTimezoneContext->status = napi_generic_failure;
395         }
396     };
397     auto complete = [env](napi_value &output) { output = NapiUtils::GetUndefinedValue(env); };
398     return NapiWork::AsyncEnqueue(env, setTimezoneContext, "SetTimezone", executor, complete);
399 }
400 
GetTimezone(napi_env env,napi_callback_info info)401 napi_value NapiSystemDateTime::GetTimezone(napi_env env, napi_callback_info info)
402 {
403     struct GetTimezoneContext : public ContextBase {
404         std::string timezone;
405     };
406     auto *getTimezoneContext = new GetTimezoneContext();
407     auto inputParser = [getTimezoneContext](size_t argc, napi_value *argv) {
408         getTimezoneContext->status = napi_ok;
409     };
410     getTimezoneContext->GetCbInfo(env, info, inputParser);
411 
412     auto executor = [getTimezoneContext]() {
413         auto innerCode = TimeServiceClient::GetInstance()->GetTimeZone(getTimezoneContext->timezone);
414         if (innerCode != JsErrorCode::ERROR_OK) {
415             getTimezoneContext->errCode = innerCode;
416             getTimezoneContext->status = napi_generic_failure;
417         }
418     };
419     auto complete = [env, getTimezoneContext](napi_value &output) {
420         getTimezoneContext->status = napi_create_string_utf8(env, getTimezoneContext->timezone.c_str(),
421             getTimezoneContext->timezone.size(), &output);
422         TIME_HILOGI(TIME_MODULE_JS_NAPI, "%{public}s, ", getTimezoneContext->timezone.c_str());
423         CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, getTimezoneContext,
424             "convert native object to javascript object failed", JsErrorCode::ERROR);
425     };
426     return NapiWork::AsyncEnqueue(env, getTimezoneContext, "GetTimezone", executor, complete);
427 }
428 
GetTimezoneSync(napi_env env,napi_callback_info info)429 napi_value NapiSystemDateTime::GetTimezoneSync(napi_env env, napi_callback_info info)
430 {
431     struct GetTimezoneContext : public ContextBase {
432         std::string timezone;
433     };
434     auto *getTimezoneContext = new GetTimezoneContext();
435     auto inputParser = [getTimezoneContext](size_t argc, napi_value *argv) { getTimezoneContext->status = napi_ok; };
436     getTimezoneContext->GetCbInfo(env, info, inputParser, true);
437 
438     auto executor = [getTimezoneContext]() {
439         auto innerCode = GetTimezone(getTimezoneContext->timezone);
440         if (innerCode != JsErrorCode::ERROR_OK) {
441             getTimezoneContext->errCode = innerCode;
442             getTimezoneContext->status = napi_generic_failure;
443         }
444     };
445     auto complete = [env, getTimezoneContext](napi_value &output) {
446         getTimezoneContext->status = napi_create_string_utf8(env, getTimezoneContext->timezone.c_str(),
447             getTimezoneContext->timezone.size(), &output);
448         CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, getTimezoneContext,
449             "convert native object to javascript object failed", JsErrorCode::ERROR);
450     };
451     return NapiWork::SyncEnqueue(env, getTimezoneContext, "GetTimezone", executor, complete);
452 }
453 
GetDeviceTime(clockid_t clockId,bool isNano,int64_t & time)454 int32_t NapiSystemDateTime::GetDeviceTime(clockid_t clockId, bool isNano, int64_t &time)
455 {
456     struct timespec tv {};
457     if (clock_gettime(clockId, &tv) < 0) {
458         TIME_HILOGE(TIME_MODULE_SERVICE, "failed clock_gettime, errno: %{public}s", strerror(errno));
459         return ERROR;
460     }
461 
462     if (isNano) {
463         time = tv.tv_sec * SECONDS_TO_NANO + tv.tv_nsec;
464     } else {
465         time = tv.tv_sec * SECONDS_TO_MILLI + tv.tv_nsec / NANO_TO_MILLI;
466     }
467     return ERROR_OK;
468 }
469 
GetTimezone(std::string & timezone)470 int32_t NapiSystemDateTime::GetTimezone(std::string &timezone)
471 {
472     timezone = system::GetParameter(TIMEZONE_KEY, "Asia/Shanghai");
473     if (timezone.empty()) {
474         TIME_HILOGW(TIME_MODULE_SERVICE, "No found timezone from system parameter.");
475         return ERROR;
476     }
477     return ERROR_OK;
478 }
479 } // namespace Time
480 } // namespace MiscServices
481 } // namespace OHOS