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