1/* 2 * Copyright (c) 2021-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#include "i18n_calendar.h" 16 17#include "buddhcal.h" 18#include "chnsecal.h" 19#include "coptccal.h" 20#include "ethpccal.h" 21#include "hebrwcal.h" 22#include "indiancal.h" 23#include "islamcal.h" 24#include "japancal.h" 25#include "unicode/locdspnm.h" 26#include "persncal.h" 27#include "string" 28#include "ureslocs.h" 29#include "ulocimp.h" 30#include "unicode/umachine.h" 31#include "unicode/gregocal.h" 32#include "unicode/timezone.h" 33#include "unicode/unistr.h" 34#include "unicode/urename.h" 35#include "ustr_imp.h" 36#include "unicode/ustring.h" 37#include "utils.h" 38 39namespace OHOS { 40namespace Global { 41namespace I18n { 42I18nCalendar::I18nCalendar(std::string localeTag) 43{ 44 UErrorCode status = U_ZERO_ERROR; 45 icu::Locale tempLocale = icu::Locale::forLanguageTag(localeTag, status); 46 if (U_FAILURE(status)) { 47 calendar_ = new icu::GregorianCalendar(status); 48 if (!U_SUCCESS(status)) { 49 if (calendar_ != nullptr) { 50 delete calendar_; 51 } 52 calendar_ = nullptr; 53 } 54 return; 55 } 56 calendar_ = icu::Calendar::createInstance(tempLocale, status); 57 if (U_FAILURE(status)) { 58 if (calendar_ != nullptr) { 59 delete calendar_; 60 } 61 calendar_ = nullptr; 62 } 63} 64 65I18nCalendar::I18nCalendar(std::string localeTag, CalendarType type) 66{ 67 UErrorCode status = U_ZERO_ERROR; 68 icu::Locale tempLocale = icu::Locale::forLanguageTag(localeTag, status); 69 if (U_FAILURE(status)) { 70 calendar_ = new icu::GregorianCalendar(status); 71 if (!U_SUCCESS(status)) { 72 if (calendar_ != nullptr) { 73 delete calendar_; 74 } 75 calendar_ = nullptr; 76 } 77 return; 78 } 79 InitCalendar(tempLocale, type); 80} 81 82void I18nCalendar::InitCalendar(const icu::Locale &locale, CalendarType type) 83{ 84 UErrorCode status = U_ZERO_ERROR; 85 switch (type) { 86 case BUDDHIST: { 87 calendar_ = new icu::BuddhistCalendar(locale, status); 88 break; 89 } 90 case CHINESE: { 91 calendar_ = new icu::ChineseCalendar(locale, status); 92 break; 93 } 94 case COPTIC: { 95 calendar_ = new icu::CopticCalendar(locale, status); 96 break; 97 } 98 case ETHIOPIC: { 99 calendar_ = new icu::EthiopicCalendar(locale, status); 100 break; 101 } 102 case HEBREW: { 103 calendar_ = new icu::HebrewCalendar(locale, status); 104 break; 105 } 106 case INDIAN: { 107 calendar_ = new icu::IndianCalendar(locale, status); 108 break; 109 } 110 case ISLAMIC_CIVIL: { 111 calendar_ = new icu::IslamicCalendar(locale, status, icu::IslamicCalendar::ECalculationType::CIVIL); 112 break; 113 } 114 default: { 115 InitCalendar2(locale, type, status); 116 } 117 } 118 if (!U_SUCCESS(status)) { 119 if (calendar_ != nullptr) { 120 delete calendar_; 121 } 122 calendar_ = nullptr; 123 } 124} 125 126void I18nCalendar::InitCalendar2(const icu::Locale &locale, CalendarType type, UErrorCode &status) 127{ 128 switch (type) { 129 case ISLAMIC_TBLA: { 130 calendar_ = new icu::IslamicCalendar(locale, status, icu::IslamicCalendar::ECalculationType::TBLA); 131 break; 132 } 133 case ISLAMIC_UMALQURA: { 134 calendar_ = new icu::IslamicCalendar(locale, status, icu::IslamicCalendar::ECalculationType::UMALQURA); 135 break; 136 } 137 case JAPANESE: { 138 calendar_ = new icu::JapaneseCalendar(locale, status); 139 break; 140 } 141 case PERSIAN: { 142 calendar_ = new icu::PersianCalendar(locale, status); 143 break; 144 } 145 case GREGORY: { 146 calendar_ = new icu::GregorianCalendar(locale, status); 147 break; 148 } 149 default: { 150 calendar_ = icu::Calendar::createInstance(locale, status); 151 } 152 } 153} 154 155I18nCalendar::~I18nCalendar() 156{ 157 if (calendar_ != nullptr) { 158 delete calendar_; 159 } 160} 161 162void I18nCalendar::SetTime(double value) 163{ 164 icu::Calendar* icuCalendar = GetIcuCalendar(); 165 if (icuCalendar != nullptr) { 166 UErrorCode status = U_ZERO_ERROR; 167 icuCalendar->setTime(value, status); 168 return; 169 } 170} 171 172void I18nCalendar::SetTimeZone(std::string id) 173{ 174 icu::UnicodeString zone = icu::UnicodeString::fromUTF8(id); 175 icu::TimeZone *timezone = icu::TimeZone::createTimeZone(zone); 176 if (timezone != nullptr) { 177 icu::Calendar* icuCalendar = GetIcuCalendar(); 178 if (icuCalendar != nullptr) { 179 icuCalendar->setTimeZone(*timezone); 180 } 181 delete(timezone); 182 } 183} 184 185std::string I18nCalendar::GetTimeZone(void) 186{ 187 std::string ret; 188 icu::Calendar* icuCalendar = GetIcuCalendar(); 189 if (icuCalendar) { 190 icu::UnicodeString unistr; 191 icuCalendar->getTimeZone().getID(unistr); 192 unistr.toUTF8String<std::string>(ret); 193 } 194 return ret; 195} 196 197void I18nCalendar::Set(int32_t year, int32_t month, int32_t date) 198{ 199 icu::Calendar* icuCalendar = GetIcuCalendar(); 200 if (icuCalendar != nullptr) { 201 icuCalendar->set(year, month, date); 202 return; 203 } 204} 205 206void I18nCalendar::Set(UCalendarDateFields field, int32_t value) 207{ 208 icu::Calendar* icuCalendar = GetIcuCalendar(); 209 if (icuCalendar != nullptr) { 210 icuCalendar->set(field, value); 211 return; 212 } 213} 214 215int32_t I18nCalendar::Get(UCalendarDateFields field) const 216{ 217 icu::Calendar* icuCalendar = GetIcuCalendar(); 218 if (icuCalendar != nullptr) { 219 UErrorCode status = U_ZERO_ERROR; 220 return icuCalendar->get(field, status); 221 } 222 return 0; 223} 224 225void I18nCalendar::Add(UCalendarDateFields field, int32_t amount) 226{ 227 icu::Calendar* icuCalendar = GetIcuCalendar(); 228 if (icuCalendar != nullptr) { 229 UErrorCode status = U_ZERO_ERROR; 230 icuCalendar->add(field, amount, status); 231 } 232} 233 234void I18nCalendar::SetMinimalDaysInFirstWeek(int32_t value) 235{ 236 icu::Calendar* icuCalendar = GetIcuCalendar(); 237 if (icuCalendar != nullptr) { 238 icuCalendar->setMinimalDaysInFirstWeek((uint8_t)value); 239 return; 240 } 241} 242 243void I18nCalendar::SetFirstDayOfWeek(int32_t value) 244{ 245 if (value < UCalendarDaysOfWeek::UCAL_SUNDAY || value > UCAL_SATURDAY) { 246 return; 247 } 248 icu::Calendar* icuCalendar = GetIcuCalendar(); 249 if (icuCalendar != nullptr) { 250 icuCalendar->setFirstDayOfWeek(UCalendarDaysOfWeek(value)); 251 return; 252 } 253} 254 255UDate I18nCalendar::GetTimeInMillis(void) 256{ 257 icu::Calendar* icuCalendar = GetIcuCalendar(); 258 if (icuCalendar != nullptr) { 259 UErrorCode status = U_ZERO_ERROR; 260 return icuCalendar->getTime(status); 261 } 262 return 0; 263} 264 265int32_t I18nCalendar::GetMinimalDaysInFirstWeek(void) 266{ 267 icu::Calendar* icuCalendar = GetIcuCalendar(); 268 if (icuCalendar != nullptr) { 269 return icuCalendar->getMinimalDaysInFirstWeek(); 270 } 271 return 1; 272} 273 274int32_t I18nCalendar::GetFirstDayOfWeek(void) 275{ 276 icu::Calendar* icuCalendar = GetIcuCalendar(); 277 if (icuCalendar != nullptr) { 278 return static_cast<int>(icuCalendar->getFirstDayOfWeek()); 279 } 280 return UCAL_SUNDAY; 281} 282 283bool I18nCalendar::IsWeekend(int64_t date, UErrorCode &status) 284{ 285 icu::Calendar* icuCalendar = GetIcuCalendar(); 286 if (icuCalendar != nullptr) { 287 return icuCalendar->isWeekend(date, status); 288 } 289 return false; 290} 291 292bool I18nCalendar::IsWeekend(void) 293{ 294 icu::Calendar* icuCalendar = GetIcuCalendar(); 295 if (icuCalendar != nullptr) { 296 return icuCalendar->isWeekend(); 297 } 298 return false; 299} 300 301std::string I18nCalendar::GetDisplayName(std::string &displayLocaleTag) 302{ 303 icu::Calendar* icuCalendar = GetIcuCalendar(); 304 if (icuCalendar == nullptr) { 305 return PseudoLocalizationProcessor(""); 306 } 307 const char *type = icuCalendar->getType(); 308 if (type == nullptr) { 309 return PseudoLocalizationProcessor(""); 310 } 311 UErrorCode status = U_ZERO_ERROR; 312 icu::Locale displayLocale = icu::Locale::forLanguageTag(displayLocaleTag, status); 313 if (U_FAILURE(status)) { 314 return PseudoLocalizationProcessor(""); 315 } 316 icu::LocaleDisplayNames *dspName = icu::LocaleDisplayNames::createInstance(displayLocale); 317 icu::UnicodeString unistr; 318 if (dspName != nullptr) { 319 dspName->keyValueDisplayName("calendar", type, unistr); 320 delete dspName; 321 } 322 std::string ret; 323 unistr.toUTF8String<std::string>(ret); 324 return PseudoLocalizationProcessor(ret); 325} 326 327int32_t I18nCalendar::CompareDays(UDate date) 328{ 329 icu::Calendar* icuCalendar = GetIcuCalendar(); 330 if (icuCalendar != nullptr) { 331 UErrorCode status = U_ZERO_ERROR; 332 UDate nowMs = icuCalendar->getTime(status); 333 double ret = (date - nowMs) / (24 * 60 * 60 * 1000); // Convert 24 hours into milliseconds 334 return ret > 0 ? std::ceil(ret) : std::floor(ret); 335 } 336 return 0; 337} 338 339icu::Calendar* I18nCalendar::GetIcuCalendar() const 340{ 341 return this->calendar_; 342} 343} // namespace I18n 344} // namespace Global 345} // namespace OHOS