• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
39 namespace OHOS {
40 namespace Global {
41 namespace I18n {
I18nCalendar(std::string localeTag)42 I18nCalendar::I18nCalendar(std::string localeTag)
43 {
44     UErrorCode status = U_ZERO_ERROR;
45     icu::Locale tempLocale = icu::Locale::forLanguageTag(localeTag, status);
46     if (status != U_ZERO_ERROR) {
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 (status != U_ZERO_ERROR) {
58         if (calendar_ != nullptr) {
59             delete calendar_;
60         }
61         calendar_ = nullptr;
62     }
63 }
64 
I18nCalendar(std::string localeTag,CalendarType type)65 I18nCalendar::I18nCalendar(std::string localeTag, CalendarType type)
66 {
67     UErrorCode status = U_ZERO_ERROR;
68     icu::Locale tempLocale = icu::Locale::forLanguageTag(localeTag, status);
69     if (status != U_ZERO_ERROR) {
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 
InitCalendar(const icu::Locale & locale,CalendarType type)82 void 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 
InitCalendar2(const icu::Locale & locale,CalendarType type,UErrorCode & status)126 void 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 
~I18nCalendar()155 I18nCalendar::~I18nCalendar()
156 {
157     if (calendar_ != nullptr) {
158         delete calendar_;
159     }
160 }
161 
SetTime(double value)162 void I18nCalendar::SetTime(double value)
163 {
164     if (calendar_ != nullptr) {
165         UErrorCode status = U_ZERO_ERROR;
166         calendar_->setTime(value, status);
167         return;
168     }
169 }
170 
SetTimeZone(std::string id)171 void I18nCalendar::SetTimeZone(std::string id)
172 {
173     icu::UnicodeString zone = icu::UnicodeString::fromUTF8(id);
174     icu::TimeZone *timezone = icu::TimeZone::createTimeZone(zone);
175     if (!timezone) {
176         return;
177     }
178     if (calendar_ != nullptr) {
179         calendar_->setTimeZone(*timezone);
180     }
181     delete(timezone);
182 }
183 
GetTimeZone(void)184 std::string I18nCalendar::GetTimeZone(void)
185 {
186     std::string ret;
187     if (calendar_) {
188         icu::UnicodeString unistr;
189         calendar_->getTimeZone().getID(unistr);
190         unistr.toUTF8String<std::string>(ret);
191     }
192     return ret;
193 }
194 
Set(int32_t year,int32_t month,int32_t date)195 void I18nCalendar::Set(int32_t year, int32_t month, int32_t date)
196 {
197     if (calendar_ != nullptr) {
198         calendar_->set(year, month, date);
199         return;
200     }
201 }
202 
Set(UCalendarDateFields field,int32_t value)203 void I18nCalendar::Set(UCalendarDateFields field, int32_t value)
204 {
205     if (calendar_ != nullptr) {
206         calendar_->set(field, value);
207         return;
208     }
209 }
210 
Get(UCalendarDateFields field) const211 int32_t I18nCalendar::Get(UCalendarDateFields field) const
212 {
213     if (calendar_ != nullptr) {
214         UErrorCode status = U_ZERO_ERROR;
215         return calendar_->get(field, status);
216     }
217     return 0;
218 }
219 
Add(UCalendarDateFields field,int32_t amount)220 void I18nCalendar::Add(UCalendarDateFields field, int32_t amount)
221 {
222     if (calendar_ != nullptr) {
223         UErrorCode status = U_ZERO_ERROR;
224         calendar_->add(field, amount, status);
225     }
226 }
227 
SetMinimalDaysInFirstWeek(int32_t value)228 void I18nCalendar::SetMinimalDaysInFirstWeek(int32_t value)
229 {
230     if (calendar_ != nullptr) {
231         calendar_->setMinimalDaysInFirstWeek((uint8_t)value);
232         return;
233     }
234 }
235 
SetFirstDayOfWeek(int32_t value)236 void I18nCalendar::SetFirstDayOfWeek(int32_t value)
237 {
238     if (value < UCalendarDaysOfWeek::UCAL_SUNDAY || value > UCAL_SATURDAY) {
239         return;
240     }
241     if (calendar_ != nullptr) {
242         calendar_->setFirstDayOfWeek(UCalendarDaysOfWeek(value));
243         return;
244     }
245 }
246 
GetTimeInMillis(void)247 UDate I18nCalendar::GetTimeInMillis(void)
248 {
249     if (calendar_ != nullptr) {
250         UErrorCode status = U_ZERO_ERROR;
251         return calendar_->getTime(status);
252     }
253     return 0;
254 }
255 
GetMinimalDaysInFirstWeek(void)256 int32_t I18nCalendar::GetMinimalDaysInFirstWeek(void)
257 {
258     if (calendar_ != nullptr) {
259         return calendar_->getMinimalDaysInFirstWeek();
260     }
261     return 1;
262 }
263 
GetFirstDayOfWeek(void)264 int32_t I18nCalendar::GetFirstDayOfWeek(void)
265 {
266     if (calendar_ != nullptr) {
267         return static_cast<int>(calendar_->getFirstDayOfWeek());
268     }
269     return UCAL_SUNDAY;
270 }
271 
IsWeekend(int64_t date,UErrorCode & status)272 bool I18nCalendar::IsWeekend(int64_t date, UErrorCode &status)
273 {
274     if (calendar_ != nullptr) {
275         return calendar_->isWeekend(date, status);
276     }
277     return false;
278 }
279 
IsWeekend(void)280 bool I18nCalendar::IsWeekend(void)
281 {
282     if (calendar_ != nullptr) {
283         return calendar_->isWeekend();
284     }
285     return false;
286 }
287 
GetDisplayName(std::string & displayLocaleTag)288 std::string I18nCalendar::GetDisplayName(std::string &displayLocaleTag)
289 {
290     if (calendar_ == nullptr) {
291         return PseudoLocalizationProcessor("");
292     }
293     const char *type = calendar_->getType();
294     if (type == nullptr) {
295         return PseudoLocalizationProcessor("");
296     }
297     UErrorCode status = U_ZERO_ERROR;
298     icu::Locale displayLocale = icu::Locale::forLanguageTag(displayLocaleTag, status);
299     if (status != U_ZERO_ERROR) {
300         return PseudoLocalizationProcessor("");
301     }
302     icu::LocaleDisplayNames *dspName = icu::LocaleDisplayNames::createInstance(displayLocale);
303     icu::UnicodeString unistr;
304     if (dspName != nullptr) {
305         dspName->keyValueDisplayName("calendar", type, unistr);
306         delete dspName;
307     }
308     std::string ret;
309     unistr.toUTF8String<std::string>(ret);
310     return PseudoLocalizationProcessor(ret);
311 }
312 
CompareDays(UDate date)313 int32_t I18nCalendar::CompareDays(UDate date)
314 {
315     if (calendar_ != nullptr) {
316         UErrorCode status = U_ZERO_ERROR;
317         UDate nowMs = calendar_->getTime(status);
318         double ret = (date - nowMs) / (24 * 60 * 60 * 1000); // Convert 24 hours into milliseconds
319         return ret > 0 ? std::ceil(ret) : std::floor(ret);
320     }
321     return 0;
322 }
323 } // namespace I18n
324 } // namespace Global
325 } // namespace OHOS