1/* 2 * Copyright (c) 2023 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 <unordered_map> 17#include <unordered_set> 18 19#include "error_util.h" 20#include "i18n_hilog.h" 21#include "i18n_calendar_addon.h" 22#include "js_utils.h" 23#include "variable_convertor.h" 24 25namespace OHOS { 26namespace Global { 27namespace I18n { 28static thread_local napi_ref* g_constructor = nullptr; 29static std::unordered_map<std::string, UCalendarDateFields> g_fieldsMap { 30 { "era", UCAL_ERA }, 31 { "year", UCAL_YEAR }, 32 { "month", UCAL_MONTH }, 33 { "week_of_year", UCAL_WEEK_OF_YEAR }, 34 { "week_of_month", UCAL_WEEK_OF_MONTH }, 35 { "date", UCAL_DATE }, 36 { "day_of_year", UCAL_DAY_OF_YEAR }, 37 { "day_of_week", UCAL_DAY_OF_WEEK }, 38 { "day_of_week_in_month", UCAL_DAY_OF_WEEK_IN_MONTH }, 39 { "ap_pm", UCAL_AM_PM }, 40 { "hour", UCAL_HOUR }, 41 { "hour_of_day", UCAL_HOUR_OF_DAY }, 42 { "minute", UCAL_MINUTE }, 43 { "second", UCAL_SECOND }, 44 { "millisecond", UCAL_MILLISECOND }, 45 { "zone_offset", UCAL_ZONE_OFFSET }, 46 { "dst_offset", UCAL_DST_OFFSET }, 47 { "year_woy", UCAL_YEAR_WOY }, 48 { "dow_local", UCAL_DOW_LOCAL }, 49 { "extended_year", UCAL_EXTENDED_YEAR }, 50 { "julian_day", UCAL_JULIAN_DAY }, 51 { "milliseconds_in_day", UCAL_MILLISECONDS_IN_DAY }, 52 { "is_leap_month", UCAL_IS_LEAP_MONTH }, 53}; 54static std::unordered_set<std::string> g_fieldsInFunctionAdd { 55 "year", "month", "date", "hour", "minute", "second", "millisecond", 56 "week_of_year", "week_of_month", "day_of_year", "day_of_week", 57 "day_of_week_in_month", "hour_of_day", "milliseconds_in_day", 58}; 59static std::unordered_map<std::string, CalendarType> g_typeMap { 60 { "buddhist", CalendarType::BUDDHIST }, 61 { "chinese", CalendarType::CHINESE }, 62 { "coptic", CalendarType::COPTIC }, 63 { "ethiopic", CalendarType::ETHIOPIC }, 64 { "hebrew", CalendarType::HEBREW }, 65 { "gregory", CalendarType::GREGORY }, 66 { "indian", CalendarType::INDIAN }, 67 { "islamic_civil", CalendarType::ISLAMIC_CIVIL }, 68 { "islamic_tbla", CalendarType::ISLAMIC_TBLA }, 69 { "islamic_umalqura", CalendarType::ISLAMIC_UMALQURA }, 70 { "japanese", CalendarType::JAPANESE }, 71 { "persion", CalendarType::PERSIAN }, 72}; 73 74I18nCalendarAddon::I18nCalendarAddon() {} 75 76I18nCalendarAddon::~I18nCalendarAddon() {} 77 78void I18nCalendarAddon::Destructor(napi_env env, void *nativeObject, void *hint) 79{ 80 if (!nativeObject) { 81 return; 82 } 83 delete reinterpret_cast<I18nCalendarAddon *>(nativeObject); 84 nativeObject = nullptr; 85} 86 87napi_value I18nCalendarAddon::InitI18nCalendar(napi_env env, napi_value exports) 88{ 89 napi_property_descriptor properties[] = { 90 DECLARE_NAPI_FUNCTION("setTime", SetTime), 91 DECLARE_NAPI_FUNCTION("set", Set), 92 DECLARE_NAPI_FUNCTION("getTimeZone", GetTimeZone), 93 DECLARE_NAPI_FUNCTION("setTimeZone", SetTimeZone), 94 DECLARE_NAPI_FUNCTION("getFirstDayOfWeek", GetFirstDayOfWeek), 95 DECLARE_NAPI_FUNCTION("setFirstDayOfWeek", SetFirstDayOfWeek), 96 DECLARE_NAPI_FUNCTION("getMinimalDaysInFirstWeek", GetMinimalDaysInFirstWeek), 97 DECLARE_NAPI_FUNCTION("setMinimalDaysInFirstWeek", SetMinimalDaysInFirstWeek), 98 DECLARE_NAPI_FUNCTION("get", Get), 99 DECLARE_NAPI_FUNCTION("add", Add), 100 DECLARE_NAPI_FUNCTION("getDisplayName", GetDisplayName), 101 DECLARE_NAPI_FUNCTION("getTimeInMillis", GetTimeInMillis), 102 DECLARE_NAPI_FUNCTION("isWeekend", IsWeekend), 103 DECLARE_NAPI_FUNCTION("compareDays", CompareDays) 104 }; 105 napi_value constructor = nullptr; 106 napi_status status = napi_define_class(env, "Calendar", NAPI_AUTO_LENGTH, I18nCalendarConstructor, nullptr, 107 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor); 108 if (status != napi_ok) { 109 HILOG_ERROR_I18N("Failed to define class at Init"); 110 return nullptr; 111 } 112 exports = I18nCalendarAddon::InitCalendar(env, exports); 113 g_constructor = new (std::nothrow) napi_ref; 114 if (!g_constructor) { 115 HILOG_ERROR_I18N("Failed to create ref at init"); 116 return nullptr; 117 } 118 status = napi_create_reference(env, constructor, 1, g_constructor); 119 if (status != napi_ok) { 120 HILOG_ERROR_I18N("Failed to create reference at init"); 121 return nullptr; 122 } 123 return exports; 124} 125 126napi_value I18nCalendarAddon::InitCalendar(napi_env env, napi_value exports) 127{ 128 napi_property_descriptor properties[] = {}; 129 napi_value constructor = nullptr; 130 napi_status status = napi_define_class(env, "I18nCalendar", NAPI_AUTO_LENGTH, JSUtils::DefaultConstructor, nullptr, 131 sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor); 132 if (status != napi_ok) { 133 HILOG_ERROR_I18N("InitCalendar: Failed to define class Calendar."); 134 return nullptr; 135 } 136 status = napi_set_named_property(env, exports, "Calendar", constructor); 137 if (status != napi_ok) { 138 HILOG_ERROR_I18N("InitCalendar: Set property failed When InitCalendar."); 139 return nullptr; 140 } 141 return exports; 142} 143 144napi_value I18nCalendarAddon::GetCalendar(napi_env env, napi_callback_info info) 145{ 146 size_t argc = 2; // retrieve 2 arguments 147 napi_value argv[2] = { 0 }; 148 argv[0] = nullptr; 149 argv[1] = nullptr; 150 napi_value thisVar = nullptr; 151 void *data = nullptr; 152 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 153 napi_value constructor = nullptr; 154 napi_status status = napi_get_reference_value(env, *g_constructor, &constructor); 155 if (status != napi_ok) { 156 HILOG_ERROR_I18N("Failed to create reference at GetCalendar"); 157 return nullptr; 158 } 159 napi_valuetype valueType = napi_valuetype::napi_undefined; 160 napi_typeof(env, argv[1], &valueType); 161 if (valueType != napi_valuetype::napi_string) { 162 status = napi_create_string_utf8(env, "", NAPI_AUTO_LENGTH, argv + 1); 163 if (status != napi_ok) { 164 return nullptr; 165 } 166 } 167 napi_value result = nullptr; 168 status = napi_new_instance(env, constructor, 2, argv, &result); // 2 arguments 169 if (status != napi_ok) { 170 HILOG_ERROR_I18N("Get calendar create instance failed"); 171 return nullptr; 172 } 173 return result; 174} 175 176napi_value I18nCalendarAddon::I18nCalendarConstructor(napi_env env, napi_callback_info info) 177{ 178 size_t argc = 2; 179 napi_value argv[2] = { 0 }; 180 argv[0] = nullptr; 181 argv[1] = nullptr; 182 napi_value thisVar = nullptr; 183 void *data = nullptr; 184 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 185 if (status != napi_ok) { 186 return nullptr; 187 } 188 napi_valuetype valueType = napi_valuetype::napi_undefined; 189 napi_typeof(env, argv[0], &valueType); 190 if (valueType != napi_valuetype::napi_string) { 191 HILOG_ERROR_I18N("CalendarConstructor: Parameter type does not match"); 192 return nullptr; 193 } 194 int32_t code = 0; 195 std::string localeTag = VariableConvertor::GetString(env, argv[0], code); 196 if (code) { 197 return nullptr; 198 } 199 CalendarType type = GetCalendarType(env, argv[1]); 200 std::unique_ptr<I18nCalendarAddon> obj = nullptr; 201 obj = std::make_unique<I18nCalendarAddon>(); 202 status = 203 napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), I18nCalendarAddon::Destructor, nullptr, nullptr); 204 if (status != napi_ok) { 205 HILOG_ERROR_I18N("CalendarConstructor: Wrap II18nAddon failed"); 206 return nullptr; 207 } 208 if (!obj->InitCalendarContext(env, info, localeTag, type)) { 209 return nullptr; 210 } 211 obj.release(); 212 return thisVar; 213} 214 215napi_value I18nCalendarAddon::SetTime(napi_env env, napi_callback_info info) 216{ 217 size_t argc = 1; 218 napi_value argv[1] = { 0 }; 219 argv[0] = nullptr; 220 napi_value thisVar = nullptr; 221 void *data = nullptr; 222 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 223 if (!argv[0]) { 224 return nullptr; 225 } 226 I18nCalendarAddon *obj = nullptr; 227 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj)); 228 if (status != napi_ok || !obj || !obj->calendar_) { 229 HILOG_ERROR_I18N("SetTime: Get calendar object failed"); 230 return nullptr; 231 } 232 napi_valuetype type = napi_valuetype::napi_undefined; 233 status = napi_typeof(env, argv[0], &type); 234 if (status != napi_ok) { 235 return nullptr; 236 } 237 if (type == napi_valuetype::napi_number) { 238 obj->SetMilliseconds(env, argv[0]); 239 return nullptr; 240 } else { 241 napi_value val = GetDate(env, argv[0]); 242 if (!val) { 243 return nullptr; 244 } 245 obj->SetMilliseconds(env, val); 246 return nullptr; 247 } 248} 249 250napi_value I18nCalendarAddon::Set(napi_env env, napi_callback_info info) 251{ 252 size_t argc = 6; // Set may have 6 arguments 253 napi_value argv[6] = { 0 }; 254 for (size_t i = 0; i < argc; ++i) { 255 argv[i] = nullptr; 256 } 257 napi_value thisVar = nullptr; 258 void *data = nullptr; 259 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 260 napi_valuetype valueType = napi_valuetype::napi_undefined; 261 napi_status status = napi_ok; 262 int32_t times[3] = { 0 }; // There are at least 3 arguments. 263 for (int i = 0; i < 3; ++i) { // There are at least 3 arguments. 264 napi_typeof(env, argv[i], &valueType); 265 if (valueType != napi_valuetype::napi_number) { 266 HILOG_ERROR_I18N("Set: Parameter type does not match"); 267 return nullptr; 268 } 269 status = napi_get_value_int32(env, argv[i], times + i); 270 if (status != napi_ok) { 271 HILOG_ERROR_I18N("Set: Retrieve time value failed"); 272 return nullptr; 273 } 274 } 275 I18nCalendarAddon *obj = nullptr; 276 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj)); 277 if (status != napi_ok || !obj || !obj->calendar_) { 278 HILOG_ERROR_I18N("Set: Get calendar object failed"); 279 return nullptr; 280 } 281 obj->calendar_->Set(times[0], times[1], times[2]); // 2 is the index of date 282 obj->SetField(env, argv[3], UCalendarDateFields::UCAL_HOUR_OF_DAY); // 3 is the index of hour 283 obj->SetField(env, argv[4], UCalendarDateFields::UCAL_MINUTE); // 4 is the index of minute 284 obj->SetField(env, argv[5], UCalendarDateFields::UCAL_SECOND); // 5 is the index of second 285 return nullptr; 286} 287 288napi_value I18nCalendarAddon::GetTimeZone(napi_env env, napi_callback_info info) 289{ 290 size_t argc = 0; 291 napi_value *argv = nullptr; 292 napi_value thisVar = nullptr; 293 void *data = nullptr; 294 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 295 I18nCalendarAddon *obj = nullptr; 296 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj)); 297 if (status != napi_ok || !obj || !obj->calendar_) { 298 HILOG_ERROR_I18N("GetTimeZone: Get calendar object failed"); 299 return nullptr; 300 } 301 std::string temp = obj->calendar_->GetTimeZone(); 302 napi_value result = nullptr; 303 status = napi_create_string_utf8(env, temp.c_str(), NAPI_AUTO_LENGTH, &result); 304 if (status != napi_ok) { 305 HILOG_ERROR_I18N("Create timezone string failed"); 306 return nullptr; 307 } 308 return result; 309} 310 311napi_value I18nCalendarAddon::SetTimeZone(napi_env env, napi_callback_info info) 312{ 313 size_t argc = 1; 314 napi_value argv[1] = { 0 }; 315 argv[0] = nullptr; 316 napi_value thisVar = nullptr; 317 void *data = nullptr; 318 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 319 napi_valuetype valueType = napi_valuetype::napi_undefined; 320 napi_typeof(env, argv[0], &valueType); 321 if (valueType != napi_valuetype::napi_string) { 322 HILOG_ERROR_I18N("SetTimeZone: Parameter type does not match"); 323 return nullptr; 324 } 325 size_t len = 0; 326 napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len); 327 if (status != napi_ok) { 328 HILOG_ERROR_I18N("SetTimeZone: Get timezone length failed"); 329 return nullptr; 330 } 331 std::vector<char> buf(len + 1); 332 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len); 333 if (status != napi_ok) { 334 HILOG_ERROR_I18N("SetTimeZone: Get timezone failed"); 335 return nullptr; 336 } 337 std::string timezone(buf.data()); 338 I18nCalendarAddon *obj = nullptr; 339 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj)); 340 if (status != napi_ok || !obj || !obj->calendar_) { 341 HILOG_ERROR_I18N("SetTimeZone: Get calendar object failed"); 342 return nullptr; 343 } 344 obj->calendar_->SetTimeZone(timezone); 345 return nullptr; 346} 347 348napi_value I18nCalendarAddon::GetFirstDayOfWeek(napi_env env, napi_callback_info info) 349{ 350 size_t argc = 0; 351 napi_value *argv = nullptr; 352 napi_value thisVar = nullptr; 353 void *data = nullptr; 354 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 355 I18nCalendarAddon *obj = nullptr; 356 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj)); 357 if (status != napi_ok || !obj || !obj->calendar_) { 358 HILOG_ERROR_I18N("GetFirstDayOfWeek: Get calendar object failed"); 359 return nullptr; 360 } 361 int32_t temp = obj->calendar_->GetFirstDayOfWeek(); 362 napi_value result = nullptr; 363 status = napi_create_int32(env, temp, &result); 364 if (status != napi_ok) { 365 HILOG_ERROR_I18N("GetFirstDayOfWeek: Create int32 failed"); 366 return nullptr; 367 } 368 return result; 369} 370 371napi_value I18nCalendarAddon::SetFirstDayOfWeek(napi_env env, napi_callback_info info) 372{ 373 size_t argc = 1; 374 napi_value argv[1] = { 0 }; 375 argv[0] = nullptr; 376 napi_value thisVar = nullptr; 377 void *data = nullptr; 378 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 379 napi_valuetype valueType = napi_valuetype::napi_undefined; 380 napi_typeof(env, argv[0], &valueType); 381 if (valueType != napi_valuetype::napi_number) { 382 HILOG_ERROR_I18N("SetFirstDayOfWeek: Parameter type does not match"); 383 return nullptr; 384 } 385 int32_t value = 0; 386 napi_status status = napi_get_value_int32(env, argv[0], &value); 387 if (status != napi_ok) { 388 HILOG_ERROR_I18N("SetFirstDayOfWeek: Get int32 failed"); 389 return nullptr; 390 } 391 I18nCalendarAddon *obj = nullptr; 392 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj)); 393 if (status != napi_ok || !obj || !obj->calendar_) { 394 HILOG_ERROR_I18N("SetFirstDayOfWeek: Get calendar object failed"); 395 return nullptr; 396 } 397 obj->calendar_->SetFirstDayOfWeek(value); 398 return nullptr; 399} 400 401napi_value I18nCalendarAddon::GetMinimalDaysInFirstWeek(napi_env env, napi_callback_info info) 402{ 403 size_t argc = 0; 404 napi_value *argv = nullptr; 405 napi_value thisVar = nullptr; 406 void *data = nullptr; 407 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 408 I18nCalendarAddon *obj = nullptr; 409 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj)); 410 if (status != napi_ok || !obj || !obj->calendar_) { 411 HILOG_ERROR_I18N("GetMinimalDaysInFirstWeek: Get calendar object failed"); 412 return nullptr; 413 } 414 int32_t temp = obj->calendar_->GetMinimalDaysInFirstWeek(); 415 napi_value result = nullptr; 416 status = napi_create_int32(env, temp, &result); 417 if (status != napi_ok) { 418 HILOG_ERROR_I18N("GetMinimalDaysInFirstWeek: Create int32 failed"); 419 return nullptr; 420 } 421 return result; 422} 423 424napi_value I18nCalendarAddon::SetMinimalDaysInFirstWeek(napi_env env, napi_callback_info info) 425{ 426 size_t argc = 1; 427 napi_value argv[1] = { 0 }; 428 argv[0] = nullptr; 429 napi_value thisVar = nullptr; 430 void *data = nullptr; 431 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 432 napi_valuetype valueType = napi_valuetype::napi_undefined; 433 napi_typeof(env, argv[0], &valueType); 434 if (valueType != napi_valuetype::napi_number) { 435 HILOG_ERROR_I18N("SetMinimalDaysInFirstWeek: Parameter type does not match"); 436 return nullptr; 437 } 438 int32_t value = 0; 439 napi_status status = napi_get_value_int32(env, argv[0], &value); 440 if (status != napi_ok) { 441 HILOG_ERROR_I18N("SetMinimalDaysInFirstWeek: Get int32 failed"); 442 return nullptr; 443 } 444 I18nCalendarAddon *obj = nullptr; 445 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj)); 446 if (status != napi_ok || !obj || !obj->calendar_) { 447 HILOG_ERROR_I18N("SetMinimalDaysInFirstWeek: Get calendar object failed"); 448 return nullptr; 449 } 450 obj->calendar_->SetMinimalDaysInFirstWeek(value); 451 return nullptr; 452} 453 454napi_value I18nCalendarAddon::Get(napi_env env, napi_callback_info info) 455{ 456 size_t argc = 1; 457 napi_value argv[1] = { 0 }; 458 argv[0] = nullptr; 459 napi_value thisVar = nullptr; 460 void *data = nullptr; 461 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 462 napi_valuetype valueType = napi_valuetype::napi_undefined; 463 napi_typeof(env, argv[0], &valueType); 464 if (valueType != napi_valuetype::napi_string) { 465 HILOG_ERROR_I18N("Get: Parameter type does not match"); 466 return nullptr; 467 } 468 size_t len = 0; 469 napi_status status = napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len); 470 if (status != napi_ok) { 471 HILOG_ERROR_I18N("Get field length failed"); 472 return nullptr; 473 } 474 std::vector<char> buf(len + 1); 475 status = napi_get_value_string_utf8(env, argv[0], buf.data(), len + 1, &len); 476 if (status != napi_ok) { 477 HILOG_ERROR_I18N("Get field failed"); 478 return nullptr; 479 } 480 std::string field(buf.data()); 481 if (g_fieldsMap.find(field) == g_fieldsMap.end()) { 482 HILOG_ERROR_I18N("Invalid field"); 483 return nullptr; 484 } 485 I18nCalendarAddon *obj = nullptr; 486 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj)); 487 if (status != napi_ok || !obj || !obj->calendar_) { 488 HILOG_ERROR_I18N("Get: Get calendar object failed"); 489 return nullptr; 490 } 491 int32_t value = obj->calendar_->Get(g_fieldsMap[field]); 492 napi_value result = nullptr; 493 status = napi_create_int32(env, value, &result); 494 if (status != napi_ok) { 495 HILOG_ERROR_I18N("Get: Create int32 failed"); 496 return nullptr; 497 } 498 return result; 499} 500 501napi_value I18nCalendarAddon::Add(napi_env env, napi_callback_info info) 502{ 503 size_t argc = 2; 504 napi_value argv[2] = { 0 }; 505 napi_value thisVar = nullptr; 506 void *data = nullptr; 507 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 508 if (status != napi_ok) { 509 HILOG_ERROR_I18N("Add: can not obtain add function param."); 510 return nullptr; 511 } 512 napi_valuetype valueType = napi_valuetype::napi_undefined; 513 napi_typeof(env, argv[0], &valueType); 514 if (valueType != napi_valuetype::napi_string) { 515 HILOG_ERROR_I18N("Parameter type does not match argv[0]"); 516 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "field", "string", true); 517 return nullptr; 518 } 519 int32_t code = 0; 520 std::string field = GetAddField(env, argv[0], code); 521 if (code) { 522 return nullptr; 523 } 524 napi_typeof(env, argv[1], &valueType); 525 if (valueType != napi_valuetype::napi_number) { 526 HILOG_ERROR_I18N("Parameter type does not match argv[1]"); 527 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "amount", "number", true); 528 return nullptr; 529 } 530 int32_t amount; 531 status = napi_get_value_int32(env, argv[1], &amount); 532 if (status != napi_ok) { 533 HILOG_ERROR_I18N("Add: Can not obtain add function param."); 534 return nullptr; 535 } 536 I18nCalendarAddon *obj = nullptr; 537 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj)); 538 if (status != napi_ok || !obj || !obj->calendar_) { 539 HILOG_ERROR_I18N("Add: Get calendar object failed"); 540 return nullptr; 541 } 542 obj->calendar_->Add(g_fieldsMap[field], amount); 543 return nullptr; 544} 545 546napi_value I18nCalendarAddon::GetDisplayName(napi_env env, napi_callback_info info) 547{ 548 size_t argc = 1; 549 napi_value argv[1] = { 0 }; 550 argv[0] = nullptr; 551 napi_value thisVar = nullptr; 552 void *data = nullptr; 553 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 554 napi_valuetype valueType = napi_valuetype::napi_undefined; 555 napi_typeof(env, argv[0], &valueType); 556 if (valueType != napi_valuetype::napi_string) { 557 HILOG_ERROR_I18N("GetDisplayName: Parameter type does not match"); 558 return nullptr; 559 } 560 int32_t code = 0; 561 std::string localeTag = VariableConvertor::GetString(env, argv[0], code); 562 if (code) { 563 return nullptr; 564 } 565 I18nCalendarAddon *obj = nullptr; 566 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj)); 567 if (status != napi_ok || !obj || !obj->calendar_) { 568 HILOG_ERROR_I18N("GetDisplayName: Get calendar object failed"); 569 return nullptr; 570 } 571 if (!obj->calendar_) { 572 return nullptr; 573 } 574 std::string name = obj->calendar_->GetDisplayName(localeTag); 575 napi_value result = nullptr; 576 status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &result); 577 if (status != napi_ok) { 578 HILOG_ERROR_I18N("Create calendar name string failed"); 579 return nullptr; 580 } 581 return result; 582} 583 584napi_value I18nCalendarAddon::GetTimeInMillis(napi_env env, napi_callback_info info) 585{ 586 bool flag = true; 587 size_t argc = 0; 588 napi_value *argv = nullptr; 589 napi_value thisVar = nullptr; 590 void *data = nullptr; 591 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 592 I18nCalendarAddon *obj = nullptr; 593 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj)); 594 if (status != napi_ok || !obj || !obj->calendar_) { 595 HILOG_ERROR_I18N("GetTimeInMillis: Get calendar object failed"); 596 flag = false; 597 } 598 UDate temp = 0; 599 if (flag) { 600 temp = obj->calendar_->GetTimeInMillis(); 601 } 602 napi_value result = nullptr; 603 status = napi_create_double(env, temp, &result); 604 if (status != napi_ok) { 605 HILOG_ERROR_I18N("Create UDate failed"); 606 napi_create_double(env, 0, &result); 607 } 608 return result; 609} 610 611napi_value I18nCalendarAddon::IsWeekend(napi_env env, napi_callback_info info) 612{ 613 size_t argc = 1; 614 napi_value argv[1] = { 0 }; 615 argv[0] = nullptr; 616 napi_value thisVar = nullptr; 617 void *data = nullptr; 618 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 619 I18nCalendarAddon *obj = nullptr; 620 bool isWeekEnd = false; 621 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj)); 622 do { 623 if (status != napi_ok || !obj || !obj->calendar_) { 624 HILOG_ERROR_I18N("IsWeekend: Get calendar object failed"); 625 break; 626 } 627 if (!VariableConvertor::CheckNapiValueType(env, argv[0])) { 628 isWeekEnd = obj->calendar_->IsWeekend(); 629 } else { 630 napi_value funcGetDateInfo = nullptr; 631 status = napi_get_named_property(env, argv[0], "valueOf", &funcGetDateInfo); 632 if (status != napi_ok) { 633 HILOG_ERROR_I18N("Get method now failed"); 634 break; 635 } 636 napi_value value = nullptr; 637 status = napi_call_function(env, argv[0], funcGetDateInfo, 0, nullptr, &value); 638 if (status != napi_ok) { 639 HILOG_ERROR_I18N("IsWeekend: Get milliseconds failed"); 640 break; 641 } 642 double milliseconds = 0; 643 status = napi_get_value_double(env, value, &milliseconds); 644 if (status != napi_ok) { 645 HILOG_ERROR_I18N("IsWeekend: Retrieve milliseconds failed"); 646 break; 647 } 648 UErrorCode error = U_ZERO_ERROR; 649 isWeekEnd = obj->calendar_->IsWeekend(milliseconds, error); 650 } 651 } while (false); 652 napi_value result = nullptr; 653 status = napi_get_boolean(env, isWeekEnd, &result); 654 if (status != napi_ok) { 655 HILOG_ERROR_I18N("Create boolean failed"); 656 return nullptr; 657 } 658 return result; 659} 660 661napi_value I18nCalendarAddon::CompareDays(napi_env env, napi_callback_info info) 662{ 663 size_t argc = 1; 664 napi_value argv[1] = { 0 }; 665 napi_value thisVar = nullptr; 666 void *data = nullptr; 667 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data); 668 napi_value result = nullptr; 669 UDate milliseconds = 0; 670 napi_status status = napi_get_date_value(env, argv[0], &milliseconds); 671 if (status != napi_ok) { 672 HILOG_ERROR_I18N("compareDays: function param is not Date"); 673 return nullptr; 674 } 675 676 I18nCalendarAddon *obj = nullptr; 677 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj)); 678 if (status != napi_ok || !obj || !obj->calendar_) { 679 HILOG_ERROR_I18N("CompareDays: Get calendar object failed"); 680 status = napi_create_int32(env, 0, &result); // if error return 0 681 return result; 682 } 683 684 int32_t diff_date = obj->calendar_->CompareDays(milliseconds); 685 status = napi_create_int32(env, diff_date, &result); 686 return result; 687} 688 689bool I18nCalendarAddon::InitCalendarContext(napi_env env, napi_callback_info info, const std::string &localeTag, 690 CalendarType type) 691{ 692 calendar_ = std::make_unique<I18nCalendar>(localeTag, type); 693 return calendar_ != nullptr; 694} 695 696CalendarType I18nCalendarAddon::GetCalendarType(napi_env env, napi_value value) 697{ 698 CalendarType type = CalendarType::UNDEFINED; 699 if (value != nullptr) { 700 napi_valuetype valueType = napi_valuetype::napi_undefined; 701 napi_typeof(env, value, &valueType); 702 if (valueType != napi_valuetype::napi_string) { 703 HILOG_ERROR_I18N("GetCalendarType: Parameter type does not match"); 704 return type; 705 } 706 int32_t code = 0; 707 std::string calendarType = VariableConvertor::GetString(env, value, code); 708 if (code) { 709 return type; 710 } 711 if (g_typeMap.find(calendarType) != g_typeMap.end()) { 712 type = g_typeMap[calendarType]; 713 } 714 } 715 return type; 716} 717 718void I18nCalendarAddon::SetField(napi_env env, napi_value value, UCalendarDateFields field) 719{ 720 if (!VariableConvertor::CheckNapiValueType(env, value)) { 721 return; 722 } 723 int32_t val = 0; 724 napi_valuetype valueType = napi_valuetype::napi_undefined; 725 napi_typeof(env, value, &valueType); 726 if (valueType != napi_valuetype::napi_number) { 727 HILOG_ERROR_I18N("SetField: Parameter type does not match"); 728 return; 729 } 730 napi_status status = napi_get_value_int32(env, value, &val); 731 if (status != napi_ok) { 732 HILOG_ERROR_I18N("SetField: Retrieve field failed"); 733 return; 734 } 735 if (calendar_ != nullptr) { 736 calendar_->Set(field, val); 737 } 738} 739 740std::string I18nCalendarAddon::GetAddField(napi_env &env, napi_value &value, int32_t &code) 741{ 742 std::string field = VariableConvertor::GetString(env, value, code); 743 if (code != 0) { 744 HILOG_ERROR_I18N("GetAddField: can't get string from js array param."); 745 return field; 746 } 747 if (g_fieldsInFunctionAdd.find(field) == g_fieldsInFunctionAdd.end()) { 748 code = 1; 749 HILOG_ERROR_I18N("Parameter rangs do not match"); 750 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, "field", "a valid field", true); 751 return field; 752 } 753 return field; 754} 755 756napi_value I18nCalendarAddon::GetDate(napi_env env, napi_value value) 757{ 758 if (!value) { 759 return nullptr; 760 } 761 napi_value funcGetDateInfo = nullptr; 762 napi_status status = napi_get_named_property(env, value, "valueOf", &funcGetDateInfo); 763 if (status != napi_ok) { 764 HILOG_ERROR_I18N("Get method valueOf failed"); 765 return nullptr; 766 } 767 napi_value ret_value = nullptr; 768 status = napi_call_function(env, value, funcGetDateInfo, 0, nullptr, &ret_value); 769 if (status != napi_ok) { 770 HILOG_ERROR_I18N("GetDate: Get milliseconds failed"); 771 return nullptr; 772 } 773 return ret_value; 774} 775 776void I18nCalendarAddon::SetMilliseconds(napi_env env, napi_value value) 777{ 778 if (!value) { 779 return; 780 } 781 double milliseconds = 0; 782 napi_valuetype valueType = napi_valuetype::napi_undefined; 783 napi_typeof(env, value, &valueType); 784 if (valueType != napi_valuetype::napi_number) { 785 HILOG_ERROR_I18N("SetMilliseconds: Parameter type does not match"); 786 return; 787 } 788 napi_status status = napi_get_value_double(env, value, &milliseconds); 789 if (status != napi_ok) { 790 HILOG_ERROR_I18N("SetMilliseconds: Retrieve milliseconds failed"); 791 return; 792 } 793 if (calendar_ != nullptr) { 794 calendar_->SetTime(milliseconds); 795 } 796} 797 798} // namespace I18n 799} // namespace Global 800} // namespace OHOS