19596a2c1Sopenharmony_ci/* 29596a2c1Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 39596a2c1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 49596a2c1Sopenharmony_ci * you may not use this file except in compliance with the License. 59596a2c1Sopenharmony_ci * You may obtain a copy of the License at 69596a2c1Sopenharmony_ci * 79596a2c1Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 89596a2c1Sopenharmony_ci * 99596a2c1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 109596a2c1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 119596a2c1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 129596a2c1Sopenharmony_ci * See the License for the specific language governing permissions and 139596a2c1Sopenharmony_ci * limitations under the License. 149596a2c1Sopenharmony_ci */ 159596a2c1Sopenharmony_ci#include "i18n_calendar.h" 169596a2c1Sopenharmony_ci 179596a2c1Sopenharmony_ci#include "buddhcal.h" 189596a2c1Sopenharmony_ci#include "chnsecal.h" 199596a2c1Sopenharmony_ci#include "coptccal.h" 209596a2c1Sopenharmony_ci#include "ethpccal.h" 219596a2c1Sopenharmony_ci#include "hebrwcal.h" 229596a2c1Sopenharmony_ci#include "indiancal.h" 239596a2c1Sopenharmony_ci#include "islamcal.h" 249596a2c1Sopenharmony_ci#include "japancal.h" 259596a2c1Sopenharmony_ci#include "unicode/locdspnm.h" 269596a2c1Sopenharmony_ci#include "persncal.h" 279596a2c1Sopenharmony_ci#include "string" 289596a2c1Sopenharmony_ci#include "ureslocs.h" 299596a2c1Sopenharmony_ci#include "ulocimp.h" 309596a2c1Sopenharmony_ci#include "unicode/umachine.h" 319596a2c1Sopenharmony_ci#include "unicode/gregocal.h" 329596a2c1Sopenharmony_ci#include "unicode/timezone.h" 339596a2c1Sopenharmony_ci#include "unicode/unistr.h" 349596a2c1Sopenharmony_ci#include "unicode/urename.h" 359596a2c1Sopenharmony_ci#include "ustr_imp.h" 369596a2c1Sopenharmony_ci#include "unicode/ustring.h" 379596a2c1Sopenharmony_ci#include "utils.h" 389596a2c1Sopenharmony_ci 399596a2c1Sopenharmony_cinamespace OHOS { 409596a2c1Sopenharmony_cinamespace Global { 419596a2c1Sopenharmony_cinamespace I18n { 429596a2c1Sopenharmony_ciI18nCalendar::I18nCalendar(std::string localeTag) 439596a2c1Sopenharmony_ci{ 449596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 459596a2c1Sopenharmony_ci icu::Locale tempLocale = icu::Locale::forLanguageTag(localeTag, status); 469596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 479596a2c1Sopenharmony_ci calendar_ = new icu::GregorianCalendar(status); 489596a2c1Sopenharmony_ci if (!U_SUCCESS(status)) { 499596a2c1Sopenharmony_ci if (calendar_ != nullptr) { 509596a2c1Sopenharmony_ci delete calendar_; 519596a2c1Sopenharmony_ci } 529596a2c1Sopenharmony_ci calendar_ = nullptr; 539596a2c1Sopenharmony_ci } 549596a2c1Sopenharmony_ci return; 559596a2c1Sopenharmony_ci } 569596a2c1Sopenharmony_ci calendar_ = icu::Calendar::createInstance(tempLocale, status); 579596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 589596a2c1Sopenharmony_ci if (calendar_ != nullptr) { 599596a2c1Sopenharmony_ci delete calendar_; 609596a2c1Sopenharmony_ci } 619596a2c1Sopenharmony_ci calendar_ = nullptr; 629596a2c1Sopenharmony_ci } 639596a2c1Sopenharmony_ci} 649596a2c1Sopenharmony_ci 659596a2c1Sopenharmony_ciI18nCalendar::I18nCalendar(std::string localeTag, CalendarType type) 669596a2c1Sopenharmony_ci{ 679596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 689596a2c1Sopenharmony_ci icu::Locale tempLocale = icu::Locale::forLanguageTag(localeTag, status); 699596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 709596a2c1Sopenharmony_ci calendar_ = new icu::GregorianCalendar(status); 719596a2c1Sopenharmony_ci if (!U_SUCCESS(status)) { 729596a2c1Sopenharmony_ci if (calendar_ != nullptr) { 739596a2c1Sopenharmony_ci delete calendar_; 749596a2c1Sopenharmony_ci } 759596a2c1Sopenharmony_ci calendar_ = nullptr; 769596a2c1Sopenharmony_ci } 779596a2c1Sopenharmony_ci return; 789596a2c1Sopenharmony_ci } 799596a2c1Sopenharmony_ci InitCalendar(tempLocale, type); 809596a2c1Sopenharmony_ci} 819596a2c1Sopenharmony_ci 829596a2c1Sopenharmony_civoid I18nCalendar::InitCalendar(const icu::Locale &locale, CalendarType type) 839596a2c1Sopenharmony_ci{ 849596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 859596a2c1Sopenharmony_ci switch (type) { 869596a2c1Sopenharmony_ci case BUDDHIST: { 879596a2c1Sopenharmony_ci calendar_ = new icu::BuddhistCalendar(locale, status); 889596a2c1Sopenharmony_ci break; 899596a2c1Sopenharmony_ci } 909596a2c1Sopenharmony_ci case CHINESE: { 919596a2c1Sopenharmony_ci calendar_ = new icu::ChineseCalendar(locale, status); 929596a2c1Sopenharmony_ci break; 939596a2c1Sopenharmony_ci } 949596a2c1Sopenharmony_ci case COPTIC: { 959596a2c1Sopenharmony_ci calendar_ = new icu::CopticCalendar(locale, status); 969596a2c1Sopenharmony_ci break; 979596a2c1Sopenharmony_ci } 989596a2c1Sopenharmony_ci case ETHIOPIC: { 999596a2c1Sopenharmony_ci calendar_ = new icu::EthiopicCalendar(locale, status); 1009596a2c1Sopenharmony_ci break; 1019596a2c1Sopenharmony_ci } 1029596a2c1Sopenharmony_ci case HEBREW: { 1039596a2c1Sopenharmony_ci calendar_ = new icu::HebrewCalendar(locale, status); 1049596a2c1Sopenharmony_ci break; 1059596a2c1Sopenharmony_ci } 1069596a2c1Sopenharmony_ci case INDIAN: { 1079596a2c1Sopenharmony_ci calendar_ = new icu::IndianCalendar(locale, status); 1089596a2c1Sopenharmony_ci break; 1099596a2c1Sopenharmony_ci } 1109596a2c1Sopenharmony_ci case ISLAMIC_CIVIL: { 1119596a2c1Sopenharmony_ci calendar_ = new icu::IslamicCalendar(locale, status, icu::IslamicCalendar::ECalculationType::CIVIL); 1129596a2c1Sopenharmony_ci break; 1139596a2c1Sopenharmony_ci } 1149596a2c1Sopenharmony_ci default: { 1159596a2c1Sopenharmony_ci InitCalendar2(locale, type, status); 1169596a2c1Sopenharmony_ci } 1179596a2c1Sopenharmony_ci } 1189596a2c1Sopenharmony_ci if (!U_SUCCESS(status)) { 1199596a2c1Sopenharmony_ci if (calendar_ != nullptr) { 1209596a2c1Sopenharmony_ci delete calendar_; 1219596a2c1Sopenharmony_ci } 1229596a2c1Sopenharmony_ci calendar_ = nullptr; 1239596a2c1Sopenharmony_ci } 1249596a2c1Sopenharmony_ci} 1259596a2c1Sopenharmony_ci 1269596a2c1Sopenharmony_civoid I18nCalendar::InitCalendar2(const icu::Locale &locale, CalendarType type, UErrorCode &status) 1279596a2c1Sopenharmony_ci{ 1289596a2c1Sopenharmony_ci switch (type) { 1299596a2c1Sopenharmony_ci case ISLAMIC_TBLA: { 1309596a2c1Sopenharmony_ci calendar_ = new icu::IslamicCalendar(locale, status, icu::IslamicCalendar::ECalculationType::TBLA); 1319596a2c1Sopenharmony_ci break; 1329596a2c1Sopenharmony_ci } 1339596a2c1Sopenharmony_ci case ISLAMIC_UMALQURA: { 1349596a2c1Sopenharmony_ci calendar_ = new icu::IslamicCalendar(locale, status, icu::IslamicCalendar::ECalculationType::UMALQURA); 1359596a2c1Sopenharmony_ci break; 1369596a2c1Sopenharmony_ci } 1379596a2c1Sopenharmony_ci case JAPANESE: { 1389596a2c1Sopenharmony_ci calendar_ = new icu::JapaneseCalendar(locale, status); 1399596a2c1Sopenharmony_ci break; 1409596a2c1Sopenharmony_ci } 1419596a2c1Sopenharmony_ci case PERSIAN: { 1429596a2c1Sopenharmony_ci calendar_ = new icu::PersianCalendar(locale, status); 1439596a2c1Sopenharmony_ci break; 1449596a2c1Sopenharmony_ci } 1459596a2c1Sopenharmony_ci case GREGORY: { 1469596a2c1Sopenharmony_ci calendar_ = new icu::GregorianCalendar(locale, status); 1479596a2c1Sopenharmony_ci break; 1489596a2c1Sopenharmony_ci } 1499596a2c1Sopenharmony_ci default: { 1509596a2c1Sopenharmony_ci calendar_ = icu::Calendar::createInstance(locale, status); 1519596a2c1Sopenharmony_ci } 1529596a2c1Sopenharmony_ci } 1539596a2c1Sopenharmony_ci} 1549596a2c1Sopenharmony_ci 1559596a2c1Sopenharmony_ciI18nCalendar::~I18nCalendar() 1569596a2c1Sopenharmony_ci{ 1579596a2c1Sopenharmony_ci if (calendar_ != nullptr) { 1589596a2c1Sopenharmony_ci delete calendar_; 1599596a2c1Sopenharmony_ci } 1609596a2c1Sopenharmony_ci} 1619596a2c1Sopenharmony_ci 1629596a2c1Sopenharmony_civoid I18nCalendar::SetTime(double value) 1639596a2c1Sopenharmony_ci{ 1649596a2c1Sopenharmony_ci icu::Calendar* icuCalendar = GetIcuCalendar(); 1659596a2c1Sopenharmony_ci if (icuCalendar != nullptr) { 1669596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 1679596a2c1Sopenharmony_ci icuCalendar->setTime(value, status); 1689596a2c1Sopenharmony_ci return; 1699596a2c1Sopenharmony_ci } 1709596a2c1Sopenharmony_ci} 1719596a2c1Sopenharmony_ci 1729596a2c1Sopenharmony_civoid I18nCalendar::SetTimeZone(std::string id) 1739596a2c1Sopenharmony_ci{ 1749596a2c1Sopenharmony_ci icu::UnicodeString zone = icu::UnicodeString::fromUTF8(id); 1759596a2c1Sopenharmony_ci icu::TimeZone *timezone = icu::TimeZone::createTimeZone(zone); 1769596a2c1Sopenharmony_ci if (timezone != nullptr) { 1779596a2c1Sopenharmony_ci icu::Calendar* icuCalendar = GetIcuCalendar(); 1789596a2c1Sopenharmony_ci if (icuCalendar != nullptr) { 1799596a2c1Sopenharmony_ci icuCalendar->setTimeZone(*timezone); 1809596a2c1Sopenharmony_ci } 1819596a2c1Sopenharmony_ci delete(timezone); 1829596a2c1Sopenharmony_ci } 1839596a2c1Sopenharmony_ci} 1849596a2c1Sopenharmony_ci 1859596a2c1Sopenharmony_cistd::string I18nCalendar::GetTimeZone(void) 1869596a2c1Sopenharmony_ci{ 1879596a2c1Sopenharmony_ci std::string ret; 1889596a2c1Sopenharmony_ci icu::Calendar* icuCalendar = GetIcuCalendar(); 1899596a2c1Sopenharmony_ci if (icuCalendar) { 1909596a2c1Sopenharmony_ci icu::UnicodeString unistr; 1919596a2c1Sopenharmony_ci icuCalendar->getTimeZone().getID(unistr); 1929596a2c1Sopenharmony_ci unistr.toUTF8String<std::string>(ret); 1939596a2c1Sopenharmony_ci } 1949596a2c1Sopenharmony_ci return ret; 1959596a2c1Sopenharmony_ci} 1969596a2c1Sopenharmony_ci 1979596a2c1Sopenharmony_civoid I18nCalendar::Set(int32_t year, int32_t month, int32_t date) 1989596a2c1Sopenharmony_ci{ 1999596a2c1Sopenharmony_ci icu::Calendar* icuCalendar = GetIcuCalendar(); 2009596a2c1Sopenharmony_ci if (icuCalendar != nullptr) { 2019596a2c1Sopenharmony_ci icuCalendar->set(year, month, date); 2029596a2c1Sopenharmony_ci return; 2039596a2c1Sopenharmony_ci } 2049596a2c1Sopenharmony_ci} 2059596a2c1Sopenharmony_ci 2069596a2c1Sopenharmony_civoid I18nCalendar::Set(UCalendarDateFields field, int32_t value) 2079596a2c1Sopenharmony_ci{ 2089596a2c1Sopenharmony_ci icu::Calendar* icuCalendar = GetIcuCalendar(); 2099596a2c1Sopenharmony_ci if (icuCalendar != nullptr) { 2109596a2c1Sopenharmony_ci icuCalendar->set(field, value); 2119596a2c1Sopenharmony_ci return; 2129596a2c1Sopenharmony_ci } 2139596a2c1Sopenharmony_ci} 2149596a2c1Sopenharmony_ci 2159596a2c1Sopenharmony_ciint32_t I18nCalendar::Get(UCalendarDateFields field) const 2169596a2c1Sopenharmony_ci{ 2179596a2c1Sopenharmony_ci icu::Calendar* icuCalendar = GetIcuCalendar(); 2189596a2c1Sopenharmony_ci if (icuCalendar != nullptr) { 2199596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 2209596a2c1Sopenharmony_ci return icuCalendar->get(field, status); 2219596a2c1Sopenharmony_ci } 2229596a2c1Sopenharmony_ci return 0; 2239596a2c1Sopenharmony_ci} 2249596a2c1Sopenharmony_ci 2259596a2c1Sopenharmony_civoid I18nCalendar::Add(UCalendarDateFields field, int32_t amount) 2269596a2c1Sopenharmony_ci{ 2279596a2c1Sopenharmony_ci icu::Calendar* icuCalendar = GetIcuCalendar(); 2289596a2c1Sopenharmony_ci if (icuCalendar != nullptr) { 2299596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 2309596a2c1Sopenharmony_ci icuCalendar->add(field, amount, status); 2319596a2c1Sopenharmony_ci } 2329596a2c1Sopenharmony_ci} 2339596a2c1Sopenharmony_ci 2349596a2c1Sopenharmony_civoid I18nCalendar::SetMinimalDaysInFirstWeek(int32_t value) 2359596a2c1Sopenharmony_ci{ 2369596a2c1Sopenharmony_ci icu::Calendar* icuCalendar = GetIcuCalendar(); 2379596a2c1Sopenharmony_ci if (icuCalendar != nullptr) { 2389596a2c1Sopenharmony_ci icuCalendar->setMinimalDaysInFirstWeek((uint8_t)value); 2399596a2c1Sopenharmony_ci return; 2409596a2c1Sopenharmony_ci } 2419596a2c1Sopenharmony_ci} 2429596a2c1Sopenharmony_ci 2439596a2c1Sopenharmony_civoid I18nCalendar::SetFirstDayOfWeek(int32_t value) 2449596a2c1Sopenharmony_ci{ 2459596a2c1Sopenharmony_ci if (value < UCalendarDaysOfWeek::UCAL_SUNDAY || value > UCAL_SATURDAY) { 2469596a2c1Sopenharmony_ci return; 2479596a2c1Sopenharmony_ci } 2489596a2c1Sopenharmony_ci icu::Calendar* icuCalendar = GetIcuCalendar(); 2499596a2c1Sopenharmony_ci if (icuCalendar != nullptr) { 2509596a2c1Sopenharmony_ci icuCalendar->setFirstDayOfWeek(UCalendarDaysOfWeek(value)); 2519596a2c1Sopenharmony_ci return; 2529596a2c1Sopenharmony_ci } 2539596a2c1Sopenharmony_ci} 2549596a2c1Sopenharmony_ci 2559596a2c1Sopenharmony_ciUDate I18nCalendar::GetTimeInMillis(void) 2569596a2c1Sopenharmony_ci{ 2579596a2c1Sopenharmony_ci icu::Calendar* icuCalendar = GetIcuCalendar(); 2589596a2c1Sopenharmony_ci if (icuCalendar != nullptr) { 2599596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 2609596a2c1Sopenharmony_ci return icuCalendar->getTime(status); 2619596a2c1Sopenharmony_ci } 2629596a2c1Sopenharmony_ci return 0; 2639596a2c1Sopenharmony_ci} 2649596a2c1Sopenharmony_ci 2659596a2c1Sopenharmony_ciint32_t I18nCalendar::GetMinimalDaysInFirstWeek(void) 2669596a2c1Sopenharmony_ci{ 2679596a2c1Sopenharmony_ci icu::Calendar* icuCalendar = GetIcuCalendar(); 2689596a2c1Sopenharmony_ci if (icuCalendar != nullptr) { 2699596a2c1Sopenharmony_ci return icuCalendar->getMinimalDaysInFirstWeek(); 2709596a2c1Sopenharmony_ci } 2719596a2c1Sopenharmony_ci return 1; 2729596a2c1Sopenharmony_ci} 2739596a2c1Sopenharmony_ci 2749596a2c1Sopenharmony_ciint32_t I18nCalendar::GetFirstDayOfWeek(void) 2759596a2c1Sopenharmony_ci{ 2769596a2c1Sopenharmony_ci icu::Calendar* icuCalendar = GetIcuCalendar(); 2779596a2c1Sopenharmony_ci if (icuCalendar != nullptr) { 2789596a2c1Sopenharmony_ci return static_cast<int>(icuCalendar->getFirstDayOfWeek()); 2799596a2c1Sopenharmony_ci } 2809596a2c1Sopenharmony_ci return UCAL_SUNDAY; 2819596a2c1Sopenharmony_ci} 2829596a2c1Sopenharmony_ci 2839596a2c1Sopenharmony_cibool I18nCalendar::IsWeekend(int64_t date, UErrorCode &status) 2849596a2c1Sopenharmony_ci{ 2859596a2c1Sopenharmony_ci icu::Calendar* icuCalendar = GetIcuCalendar(); 2869596a2c1Sopenharmony_ci if (icuCalendar != nullptr) { 2879596a2c1Sopenharmony_ci return icuCalendar->isWeekend(date, status); 2889596a2c1Sopenharmony_ci } 2899596a2c1Sopenharmony_ci return false; 2909596a2c1Sopenharmony_ci} 2919596a2c1Sopenharmony_ci 2929596a2c1Sopenharmony_cibool I18nCalendar::IsWeekend(void) 2939596a2c1Sopenharmony_ci{ 2949596a2c1Sopenharmony_ci icu::Calendar* icuCalendar = GetIcuCalendar(); 2959596a2c1Sopenharmony_ci if (icuCalendar != nullptr) { 2969596a2c1Sopenharmony_ci return icuCalendar->isWeekend(); 2979596a2c1Sopenharmony_ci } 2989596a2c1Sopenharmony_ci return false; 2999596a2c1Sopenharmony_ci} 3009596a2c1Sopenharmony_ci 3019596a2c1Sopenharmony_cistd::string I18nCalendar::GetDisplayName(std::string &displayLocaleTag) 3029596a2c1Sopenharmony_ci{ 3039596a2c1Sopenharmony_ci icu::Calendar* icuCalendar = GetIcuCalendar(); 3049596a2c1Sopenharmony_ci if (icuCalendar == nullptr) { 3059596a2c1Sopenharmony_ci return PseudoLocalizationProcessor(""); 3069596a2c1Sopenharmony_ci } 3079596a2c1Sopenharmony_ci const char *type = icuCalendar->getType(); 3089596a2c1Sopenharmony_ci if (type == nullptr) { 3099596a2c1Sopenharmony_ci return PseudoLocalizationProcessor(""); 3109596a2c1Sopenharmony_ci } 3119596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 3129596a2c1Sopenharmony_ci icu::Locale displayLocale = icu::Locale::forLanguageTag(displayLocaleTag, status); 3139596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 3149596a2c1Sopenharmony_ci return PseudoLocalizationProcessor(""); 3159596a2c1Sopenharmony_ci } 3169596a2c1Sopenharmony_ci icu::LocaleDisplayNames *dspName = icu::LocaleDisplayNames::createInstance(displayLocale); 3179596a2c1Sopenharmony_ci icu::UnicodeString unistr; 3189596a2c1Sopenharmony_ci if (dspName != nullptr) { 3199596a2c1Sopenharmony_ci dspName->keyValueDisplayName("calendar", type, unistr); 3209596a2c1Sopenharmony_ci delete dspName; 3219596a2c1Sopenharmony_ci } 3229596a2c1Sopenharmony_ci std::string ret; 3239596a2c1Sopenharmony_ci unistr.toUTF8String<std::string>(ret); 3249596a2c1Sopenharmony_ci return PseudoLocalizationProcessor(ret); 3259596a2c1Sopenharmony_ci} 3269596a2c1Sopenharmony_ci 3279596a2c1Sopenharmony_ciint32_t I18nCalendar::CompareDays(UDate date) 3289596a2c1Sopenharmony_ci{ 3299596a2c1Sopenharmony_ci icu::Calendar* icuCalendar = GetIcuCalendar(); 3309596a2c1Sopenharmony_ci if (icuCalendar != nullptr) { 3319596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 3329596a2c1Sopenharmony_ci UDate nowMs = icuCalendar->getTime(status); 3339596a2c1Sopenharmony_ci double ret = (date - nowMs) / (24 * 60 * 60 * 1000); // Convert 24 hours into milliseconds 3349596a2c1Sopenharmony_ci return ret > 0 ? std::ceil(ret) : std::floor(ret); 3359596a2c1Sopenharmony_ci } 3369596a2c1Sopenharmony_ci return 0; 3379596a2c1Sopenharmony_ci} 3389596a2c1Sopenharmony_ci 3399596a2c1Sopenharmony_ciicu::Calendar* I18nCalendar::GetIcuCalendar() const 3409596a2c1Sopenharmony_ci{ 3419596a2c1Sopenharmony_ci return this->calendar_; 3429596a2c1Sopenharmony_ci} 3439596a2c1Sopenharmony_ci} // namespace I18n 3449596a2c1Sopenharmony_ci} // namespace Global 3459596a2c1Sopenharmony_ci} // namespace OHOS