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