• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "intl_date_time_format_addon.h"
16 
17 #include <chrono>
18 #include <unordered_set>
19 #include "error_util.h"
20 #include "i18n_hilog.h"
21 #include "intl_date_time_format.h"
22 #include "js_utils.h"
23 #include "utils.h"
24 
25 namespace OHOS {
26 namespace Global {
27 namespace I18n {
28 static thread_local napi_ref* g_IntlDateTimeFormatConstructor = nullptr;
29 static constexpr int NUMBER_OF_PARAMETER = 2;
30 
IntlDateTimeFormatAddon()31 IntlDateTimeFormatAddon::IntlDateTimeFormatAddon()
32 {
33 }
34 
~IntlDateTimeFormatAddon()35 IntlDateTimeFormatAddon::~IntlDateTimeFormatAddon()
36 {
37 }
38 
Destructor(napi_env,void * nativeObject,void *)39 void IntlDateTimeFormatAddon::Destructor(napi_env /* env */, void* nativeObject, void* /* hint */)
40 {
41     if (!nativeObject) {
42         return;
43     }
44     delete reinterpret_cast<IntlDateTimeFormatAddon*>(nativeObject);
45     nativeObject = nullptr;
46 }
47 
InitIntlDateTimeFormat(napi_env env,napi_value exports)48 napi_value IntlDateTimeFormatAddon::InitIntlDateTimeFormat(napi_env env, napi_value exports)
49 {
50     napi_property_descriptor properties[] = {
51         DECLARE_NAPI_FUNCTION("format", Format),
52         DECLARE_NAPI_FUNCTION("formatToParts", FormatToParts),
53         DECLARE_NAPI_FUNCTION("formatRange", FormatRange),
54         DECLARE_NAPI_FUNCTION("formatRangeToParts", FormatRangeToParts),
55         DECLARE_NAPI_FUNCTION("resolvedOptions", ResolvedOptions),
56         DECLARE_NAPI_STATIC_FUNCTION("supportedLocalesOf", SupportedLocalesOf),
57     };
58 
59     napi_value constructor = nullptr;
60     napi_status status = napi_define_class(env, "DateTimeFormat", NAPI_AUTO_LENGTH, IntlDateTimeFormatConstructor,
61         nullptr, sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
62     if (status != napi_ok) {
63         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::InitIntlDateTimeFormat: Define class failed when InitIntlLocale.");
64         return nullptr;
65     }
66 
67     status = napi_set_named_property(env, exports, "DateTimeFormat", constructor);
68     if (status != napi_ok) {
69         HILOG_ERROR_I18N(
70             "IntlDateTimeFormatAddon::InitIntlDateTimeFormat: Set property failed when InitIntlDateTimeFormat.");
71         return nullptr;
72     }
73 
74     g_IntlDateTimeFormatConstructor = new (std::nothrow) napi_ref;
75     if (!g_IntlDateTimeFormatConstructor) {
76         HILOG_ERROR_I18N(
77             "IntlDateTimeFormatAddon::InitIntlDateTimeFormat: Failed to create DateTimeFormat ref at init.");
78         return nullptr;
79     }
80 
81     status = napi_create_reference(env, constructor, 1, g_IntlDateTimeFormatConstructor);
82     if (status != napi_ok) {
83         HILOG_ERROR_I18N(
84             "IntlDateTimeFormatAddon::InitIntlDateTimeFormat: Failed to create reference g_IntlLocaleConstructor.");
85         return nullptr;
86     }
87 
88     return exports;
89 }
90 
IntlDateTimeFormatConstructor(napi_env env,napi_callback_info info)91 napi_value IntlDateTimeFormatAddon::IntlDateTimeFormatConstructor(napi_env env, napi_callback_info info)
92 {
93     size_t argc = 2;
94     napi_value argv[2] = { nullptr };
95     napi_value thisVar = nullptr;
96     void *data = nullptr;
97     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
98     if (status != napi_ok) {
99         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::IntlDateTimeFormatConstructor: Get cb info failed.");
100         return nullptr;
101     }
102 
103     napi_value new_target;
104     status = napi_get_new_target(env, info, &new_target);
105     if (status == napi_pending_exception || new_target == nullptr) {
106         return CreateDateTimeFormatWithoutNew(env, argc, argv);
107     } else if (status != napi_ok) {
108         return nullptr;
109     }
110 
111     std::vector<std::string> localeTags;
112     if (argc > 0) {
113         int32_t code = 0;
114         std::vector<std::string> localeArray = JSUtils::GetLocaleArray(env, argv[0], code);
115         localeTags.assign(localeArray.begin(), localeArray.end());
116     }
117 
118     std::unordered_map<std::string, std::string> configs;
119     if (argc > 1) {
120         ParseConfigs(env, argv[1], configs);
121     }
122     IntlDateTimeFormatAddon* obj = new (std::nothrow) IntlDateTimeFormatAddon();
123     if (obj == nullptr) {
124         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::IntlDateTimeFormatConstructor: Create obj failed.");
125         return nullptr;
126     }
127     status = napi_wrap(env, thisVar, reinterpret_cast<void *>(obj), IntlDateTimeFormatAddon::Destructor,
128         nullptr, nullptr);
129     if (status != napi_ok) {
130         delete obj;
131         HILOG_ERROR_I18N(
132             "IntlDateTimeFormatAddon::IntlDateTimeFormatConstructor: Wrap IntlDateTimeFormatAddon failed");
133         return nullptr;
134     }
135     if (!obj->InitIntlDateTimeFormatContext(env, localeTags, configs)) {
136         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::IntlDateTimeFormatConstructor: Init IntlDateTimeFormat failed");
137         return nullptr;
138     }
139     return thisVar;
140 }
141 
CreateDateTimeFormatWithoutNew(napi_env env,size_t argc,napi_value * argv)142 napi_value IntlDateTimeFormatAddon::CreateDateTimeFormatWithoutNew(napi_env env, size_t argc, napi_value *argv)
143 {
144     napi_value exception;
145     napi_status status = napi_get_and_clear_last_exception(env, &exception);
146     if (status != napi_ok) {
147         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::CreateDateTimeFormatWithoutNew: Clear last exception failed");
148         return nullptr;
149     }
150 
151     napi_value constructor = nullptr;
152     status = napi_get_reference_value(env, *g_IntlDateTimeFormatConstructor, &constructor);
153     if (status != napi_ok || constructor == nullptr) {
154         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::CreateDateTimeFormatWithoutNew: napi_get_reference_value failed");
155         return nullptr;
156     }
157 
158     napi_value instance = nullptr;
159     status = napi_new_instance(env, constructor, argc, argv, &instance);
160     if (status != napi_ok) {
161         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::CreateDateTimeFormatWithoutNew: napi_new_instance failed");
162         return nullptr;
163     }
164     return instance;
165 }
166 
ParseConfigs(napi_env env,napi_value options,std::unordered_map<std::string,std::string> & configs)167 void IntlDateTimeFormatAddon::ParseConfigs(napi_env env, napi_value options,
168     std::unordered_map<std::string, std::string>& configs)
169 {
170     napi_valuetype type = napi_undefined;
171     napi_status status = napi_typeof(env, options, &type);
172     if (status != napi_ok) {
173         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::ParseConfigs: Get options type failed.");
174         return;
175     }
176     if (type != napi_object) {
177         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::ParseConfigs: options is not object.");
178         return;
179     }
180     std::string value;
181     std::unordered_set<std::string> keyOfTypeString = { IntlDateTimeFormat::LOCALE_MATCHER_TAG,
182         IntlDateTimeFormat::WEEK_DAY_TAG, IntlDateTimeFormat::ERA_TAG, IntlDateTimeFormat::YEAR_TAG,
183         IntlDateTimeFormat::MONTH_TAG, IntlDateTimeFormat::DAY_TAG, IntlDateTimeFormat::HOUR_TAG,
184         IntlDateTimeFormat::MINUTE_TAG, IntlDateTimeFormat::SECOND_TAG, IntlDateTimeFormat::TIME_ZONE_NAME_TAG,
185         IntlDateTimeFormat::FORMAT_MATCHER_TAG, IntlDateTimeFormat::TIME_ZONE_TAG, IntlDateTimeFormat::DATE_STYLE_TAG,
186         IntlDateTimeFormat::TIME_STYLE_TAG, IntlDateTimeFormat::HOUR_CYCLE_TAG, IntlDateTimeFormat::DAY_PERIOD_TAG,
187         IntlDateTimeFormat::CALENDAR_TAG, IntlDateTimeFormat::NUMBERING_SYSTEM_TAG
188     };
189     for (const auto& key : keyOfTypeString) {
190         if (JSUtils::GetPropertyFormObject(env, options, key, napi_string, value)) {
191             configs.insert(std::make_pair(key, value));
192         }
193     }
194     if (JSUtils::GetPropertyFormObject(env, options, IntlDateTimeFormat::HOUR12_TAG, napi_boolean, value)) {
195         configs.insert({IntlDateTimeFormat::HOUR12_TAG, value});
196     }
197     if (JSUtils::GetPropertyFormObject(env, options, IntlDateTimeFormat::FRACTIONAL_SECOND_DIGITS_TAG, napi_number,
198         value)) {
199         configs.insert({IntlDateTimeFormat::FRACTIONAL_SECOND_DIGITS_TAG, value});
200     }
201 }
202 
InitIntlDateTimeFormatContext(napi_env env,const std::vector<std::string> & localeTags,std::unordered_map<std::string,std::string> & configs)203 bool IntlDateTimeFormatAddon::InitIntlDateTimeFormatContext(napi_env env, const std::vector<std::string>& localeTags,
204     std::unordered_map<std::string, std::string>& configs)
205 {
206     std::string errMessage;
207     intlDateTimeFormat = std::make_unique<IntlDateTimeFormat>(localeTags, configs, errMessage);
208     if (!errMessage.empty()) {
209         ErrorUtil::NapiThrowUndefined(env, errMessage);
210         return false;
211     }
212     return intlDateTimeFormat != nullptr;
213 }
214 
Format(napi_env env,napi_callback_info info)215 napi_value IntlDateTimeFormatAddon::Format(napi_env env, napi_callback_info info)
216 {
217     size_t argc = 1;
218     napi_value argv[1] = { nullptr };
219     napi_value thisVar = nullptr;
220     void *data = nullptr;
221     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
222     if (status != napi_ok) {
223         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::Format: get cb info failed.");
224         return JSUtils::CreateEmptyString(env);
225     }
226     double milliseconds = 0;
227     if (argc < 1 || !GetDateTime(env, argv[0], milliseconds)) {
228         std::chrono::milliseconds ms = std::chrono::duration_cast< std::chrono::milliseconds >(
229             std::chrono::system_clock::now().time_since_epoch()
230         );
231         milliseconds = ms.count();
232     }
233 
234     IntlDateTimeFormatAddon* obj = nullptr;
235     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
236     if (status != napi_ok || !obj || !obj->intlDateTimeFormat) {
237         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::Format: unwrap IntlDateTimeFormatAddon failed.");
238         return JSUtils::CreateEmptyString(env);
239     }
240     std::string formatResult = obj->intlDateTimeFormat->Format(milliseconds);
241     napi_value result = nullptr;
242     status = napi_create_string_utf8(env, formatResult.c_str(), NAPI_AUTO_LENGTH, &result);
243     if (status != napi_ok) {
244         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::::Format: Create string failed.");
245         return JSUtils::CreateEmptyString(env);
246     }
247     return result;
248 }
249 
FormatToParts(napi_env env,napi_callback_info info)250 napi_value IntlDateTimeFormatAddon::FormatToParts(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_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
257     if (status != napi_ok) {
258         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::FormatToParts: get cb info failed.");
259         return JSUtils::CreateEmptyArray(env);
260     }
261     double milliseconds = 0;
262     if (argc < 1 || !GetDateTime(env, argv[0], milliseconds)) {
263         std::chrono::milliseconds ms = std::chrono::duration_cast< std::chrono::milliseconds >(
264             std::chrono::system_clock::now().time_since_epoch()
265         );
266         milliseconds = ms.count();
267     }
268 
269     IntlDateTimeFormatAddon* obj = nullptr;
270     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
271     if (status != napi_ok || !obj || !obj->intlDateTimeFormat) {
272         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::FormatToParts: unwrap IntlDateTimeFormatAddon failed.");
273         return JSUtils::CreateEmptyArray(env);
274     }
275     std::string errMessage;
276     std::vector<std::pair<std::string, std::string>> formatResult =
277         obj->intlDateTimeFormat->FormatToParts(milliseconds, errMessage);
278     if (!errMessage.empty()) {
279         ErrorUtil::NapiThrowUndefined(env, errMessage);
280         return nullptr;
281     }
282     return CreateFormatPart(env, formatResult);
283 }
284 
FormatRange(napi_env env,napi_callback_info info)285 napi_value IntlDateTimeFormatAddon::FormatRange(napi_env env, napi_callback_info info)
286 {
287     size_t argc = NUMBER_OF_PARAMETER;
288     napi_value argv[NUMBER_OF_PARAMETER] = { nullptr };
289     napi_value thisVar = nullptr;
290     void *data = nullptr;
291     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
292     if (status != napi_ok) {
293         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::FormatRange: get cb info failed.");
294         return JSUtils::CreateEmptyString(env);
295     } else if (argc < NUMBER_OF_PARAMETER) {
296         ErrorUtil::NapiThrowUndefined(env, "startDate or endDate is undefined");
297         return nullptr;
298     }
299 
300     double start = 0;
301     if (!GetDateTime(env, argv[0], start)) {
302         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::FormatRange: get date time from argv[0] failed.");
303         return JSUtils::CreateEmptyString(env);
304     }
305     double end = 0;
306     if (!GetDateTime(env, argv[1], end)) {
307         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::FormatRange: get date time from argv[1] failed.");
308         return JSUtils::CreateEmptyString(env);
309     }
310 
311     IntlDateTimeFormatAddon* obj = nullptr;
312     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
313     if (status != napi_ok || !obj || !obj->intlDateTimeFormat) {
314         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::FormatRange: unwrap IntlDateTimeFormatAddon failed.");
315         return JSUtils::CreateEmptyString(env);
316     }
317     std::string errMessage;
318     std::string formatResult = obj->intlDateTimeFormat->FormatRange(start, end, errMessage);
319     if (!errMessage.empty()) {
320         ErrorUtil::NapiThrowUndefined(env, errMessage);
321         return nullptr;
322     }
323     napi_value result = nullptr;
324     status = napi_create_string_utf8(env, formatResult.c_str(), NAPI_AUTO_LENGTH, &result);
325     if (status != napi_ok) {
326         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::FormatRange: Create string failed.");
327         return JSUtils::CreateEmptyString(env);
328     }
329     return result;
330 }
331 
FormatRangeToParts(napi_env env,napi_callback_info info)332 napi_value IntlDateTimeFormatAddon::FormatRangeToParts(napi_env env, napi_callback_info info)
333 {
334     size_t argc = NUMBER_OF_PARAMETER;
335     napi_value argv[NUMBER_OF_PARAMETER] = { nullptr };
336     napi_value thisVar = nullptr;
337     void *data = nullptr;
338     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
339     if (status != napi_ok) {
340         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::FormatRangeToParts: get cb info failed.");
341         return JSUtils::CreateEmptyArray(env);
342     } else if (argc < NUMBER_OF_PARAMETER) {
343         ErrorUtil::NapiThrowUndefined(env, "startDate or endDate is undefined");
344         return nullptr;
345     }
346 
347     double start = 0;
348     if (!GetDateTime(env, argv[0], start)) {
349         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::FormatRangeToParts: get date time from argv[0] failed.");
350         return JSUtils::CreateEmptyArray(env);
351     }
352     double end = 0;
353     if (!GetDateTime(env, argv[1], end)) {
354         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::FormatRangeToParts: get date time from argv[1] failed.");
355         return JSUtils::CreateEmptyArray(env);
356     }
357 
358     IntlDateTimeFormatAddon* obj = nullptr;
359     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
360     if (status != napi_ok || !obj || !obj->intlDateTimeFormat) {
361         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::FormatRangeToParts: unwrap IntlDateTimeFormatAddon failed.");
362         return JSUtils::CreateEmptyArray(env);
363     }
364     std::string errMessage;
365     std::vector<std::pair<std::string, std::string>> formatResult =
366         obj->intlDateTimeFormat->FormatRangeToParts(start, end, errMessage);
367     if (!errMessage.empty()) {
368         ErrorUtil::NapiThrowUndefined(env, errMessage);
369         return nullptr;
370     }
371     return CreateFormatPart(env, formatResult);
372 }
373 
ResolvedOptions(napi_env env,napi_callback_info info)374 napi_value IntlDateTimeFormatAddon::ResolvedOptions(napi_env env, napi_callback_info info)
375 {
376     size_t argc = NUMBER_OF_PARAMETER;
377     napi_value argv[NUMBER_OF_PARAMETER] = { nullptr };
378     napi_value thisVar = nullptr;
379     void *data = nullptr;
380     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
381     if (status != napi_ok) {
382         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::ResolvedOptions: get cb info failed.");
383         return JSUtils::CreateEmptyObject(env);
384     }
385     IntlDateTimeFormatAddon* obj = nullptr;
386     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
387     if (status != napi_ok || !obj || !obj->intlDateTimeFormat) {
388         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::ResolvedOptions: unwrap IntlDateTimeFormatAddon failed.");
389         return JSUtils::CreateEmptyObject(env);
390     }
391     std::unordered_map<std::string, std::string> configs;
392     obj->intlDateTimeFormat->ResolvedOptions(configs);
393     return CreateResolvedOptions(env, configs);
394 }
395 
SupportedLocalesOf(napi_env env,napi_callback_info info)396 napi_value IntlDateTimeFormatAddon::SupportedLocalesOf(napi_env env, napi_callback_info info)
397 {
398     size_t argc = NUMBER_OF_PARAMETER;
399     napi_value argv[NUMBER_OF_PARAMETER] = { nullptr };
400     napi_value thisVar = nullptr;
401     void *data = nullptr;
402     std::vector<std::string> resultLocales = {};
403     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
404     if (status != napi_ok) {
405         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::SupportedLocalesOf: napi get callback info failed.");
406         return JSUtils::CreateArray(env, resultLocales);
407     }
408     std::vector<std::string> localeTags;
409     if (argc > 0) {
410         int32_t code = 0;
411         std::vector<std::string> localeArray = JSUtils::GetLocaleArray(env, argv[0], code);
412         localeTags.assign(localeArray.begin(), localeArray.end());
413     }
414     std::map<std::string, std::string> map = {};
415     if (argc > 1) {
416         JSUtils::GetOptionValue(env, argv[1], "localeMatcher", map);
417     }
418     I18nErrorCode i18nStatus = I18nErrorCode::SUCCESS;
419     resultLocales = IntlDateTimeFormat::SupportedLocalesOf(localeTags, map, i18nStatus);
420     if (i18nStatus == I18nErrorCode::INVALID_PARAM) {
421         ErrorUtil::NapiThrowUndefined(env, "getStringOption failed");
422         return nullptr;
423     } else if (i18nStatus == I18nErrorCode::INVALID_LOCALE_TAG) {
424         ErrorUtil::NapiThrowUndefined(env, "invalid locale");
425         return nullptr;
426     }
427     return JSUtils::CreateArray(env, resultLocales);
428 }
429 
GetDateTime(napi_env env,napi_value time,double & milliseconds)430 bool IntlDateTimeFormatAddon::GetDateTime(napi_env env, napi_value time, double& milliseconds)
431 {
432     bool isDate = false;
433     napi_status status = napi_is_date(env, time, &isDate);
434     if (status != napi_ok) {
435         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::GetDateTime: Call napi_is_date failed.");
436         return false;
437     }
438     if (isDate) {
439         status = napi_get_date_value(env, time, &milliseconds);
440         if (status != napi_ok) {
441             HILOG_ERROR_I18N("IntlDateTimeFormatAddon::GetDateTime: Get date value failed.");
442             return false;
443         }
444         return true;
445     }
446 
447     napi_valuetype type = napi_undefined;
448     status = napi_typeof(env, time, &type);
449     if (status != napi_ok) {
450         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::GetDateTime: Get time type failed.");
451         return false;
452     }
453     if (type != napi_valuetype::napi_number) {
454         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::GetDateTime: Check type failed.");
455         return false;
456     }
457     status = napi_get_value_double(env, time, &milliseconds);
458     if (status != napi_ok) {
459         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::GetDateTime: Get get value double failed.");
460         return false;
461     }
462     return true;
463 }
464 
CreateFormatPart(napi_env env,const std::vector<std::pair<std::string,std::string>> & formatResult)465 napi_value IntlDateTimeFormatAddon::CreateFormatPart(napi_env env,
466     const std::vector<std::pair<std::string, std::string>>& formatResult)
467 {
468     size_t length = formatResult.size();
469     napi_value result = nullptr;
470     napi_status status = napi_create_array_with_length(env, length, &result);
471     if (status != napi_ok || result == nullptr) {
472         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::CreateFormatPart: Create array failed.");
473         return JSUtils::CreateEmptyArray(env);
474     }
475     size_t index = 0;
476     for (const auto& item : formatResult) {
477         napi_value object = nullptr;
478         status = napi_create_object(env, &object);
479         if (status != napi_ok || object == nullptr) {
480             HILOG_ERROR_I18N("IntlDateTimeFormatAddon::CreateFormatPart: Create object failed.");
481             return JSUtils::CreateEmptyArray(env);
482         }
483         napi_value type = nullptr;
484         status = napi_create_string_utf8(env, item.first.c_str(), NAPI_AUTO_LENGTH, &type);
485         if (status != napi_ok || type == nullptr) {
486             HILOG_ERROR_I18N("IntlDateTimeFormatAddon::CreateFormatPart: Create type failed.");
487             return JSUtils::CreateEmptyArray(env);
488         }
489         status = napi_set_named_property(env, object, "type", type);
490         if (status != napi_ok) {
491             HILOG_ERROR_I18N("IntlDateTimeFormatAddon::CreateFormatPart: Set property type failed.");
492             return JSUtils::CreateEmptyArray(env);
493         }
494         napi_value value = nullptr;
495         status = napi_create_string_utf8(env, item.second.c_str(), NAPI_AUTO_LENGTH, &value);
496         if (status != napi_ok || value == nullptr) {
497             HILOG_ERROR_I18N("IntlDateTimeFormatAddon::CreateFormatPart: Create type failed.");
498             return JSUtils::CreateEmptyArray(env);
499         }
500         status = napi_set_named_property(env, object, "value", value);
501         if (status != napi_ok) {
502             HILOG_ERROR_I18N("IntlDateTimeFormatAddon::CreateFormatPart: Set property type failed.");
503             return JSUtils::CreateEmptyArray(env);
504         }
505         status = napi_set_element(env, result, index, object);
506         if (status != napi_ok) {
507             HILOG_ERROR_I18N("IntlDateTimeFormatAddon::CreateFormatPart: Set element failed, index is %{public}zu.",
508                 index);
509             return JSUtils::CreateEmptyArray(env);
510         }
511         index++;
512     }
513     return result;
514 }
515 
CreateResolvedOptions(napi_env env,const std::unordered_map<std::string,std::string> & configs)516 napi_value IntlDateTimeFormatAddon::CreateResolvedOptions(napi_env env,
517     const std::unordered_map<std::string, std::string>& configs)
518 {
519     napi_value object = nullptr;
520     napi_status status = napi_create_object(env, &object);
521     if (status != napi_ok || object == nullptr) {
522         HILOG_ERROR_I18N("IntlDateTimeFormatAddon::CreateFormatPart: Create object failed.");
523         return JSUtils::CreateEmptyObject(env);
524     }
525 
526     for (auto& config : configs) {
527         std::string key = config.first;
528         std::string value = config.second;
529         napi_value propertyValue = nullptr;
530         if (key.compare(IntlDateTimeFormat::HOUR12_TAG) == 0) {
531             bool boolValue = (value.compare("true") == 0) ? true : false;
532             status = napi_get_boolean(env, boolValue, &propertyValue);
533         } else if (key.compare(IntlDateTimeFormat::FRACTIONAL_SECOND_DIGITS_TAG) == 0) {
534             int32_t code = 0;
535             int32_t intValue = ConvertString2Int(value, code);
536             if (code != 0) {
537                 HILOG_ERROR_I18N("IntlDateTimeFormatAddon::CreateResolvedOptions: Convert string failed.");
538                 continue;
539             }
540             status = napi_create_int32(env, intValue, &propertyValue);
541         } else {
542             status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &propertyValue);
543         }
544         if (status != napi_ok || propertyValue == nullptr) {
545             HILOG_ERROR_I18N("IntlDateTimeFormatAddon::CreateResolvedOptions: Create propertyValue failed.");
546             continue;
547         }
548         status = napi_set_named_property(env, object, key.c_str(), propertyValue);
549         if (status != napi_ok) {
550             HILOG_ERROR_I18N("IntlDateTimeFormatAddon::CreateResolvedOptions: Set property failed.");
551         }
552     }
553     return object;
554 }
555 } // namespace I18n
556 } // namespace Global
557 } // namespace OHOS