1 /*
2 * Copyright (c) 2024 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 <string>
17 #include <unordered_map>
18 #include <unordered_set>
19 #include <ctime>
20 #include "i18n_calendar_ffi.h"
21 #include "i18n_calendar_impl.h"
22 #include "unicode/ucal.h"
23 #include "i18n_ffi.h"
24 #include "i18n_hilog.h"
25
26 namespace {
27 using namespace OHOS::Global::I18n;
28 constexpr uint32_t HOUR_FLAG = 4;
29 constexpr uint32_t MINUTE_FLAG = 2;
30 constexpr uint32_t SECOND_FLAG = 1;
31 std::unordered_map<std::string, UCalendarDateFields> g_fieldsMap {
32 { "era", UCAL_ERA },
33 { "year", UCAL_YEAR },
34 { "month", UCAL_MONTH },
35 { "week_of_year", UCAL_WEEK_OF_YEAR },
36 { "week_of_month", UCAL_WEEK_OF_MONTH },
37 { "date", UCAL_DATE },
38 { "day_of_year", UCAL_DAY_OF_YEAR },
39 { "day_of_week", UCAL_DAY_OF_WEEK },
40 { "day_of_week_in_month", UCAL_DAY_OF_WEEK_IN_MONTH },
41 { "ap_pm", UCAL_AM_PM },
42 { "hour", UCAL_HOUR },
43 { "hour_of_day", UCAL_HOUR_OF_DAY },
44 { "minute", UCAL_MINUTE },
45 { "second", UCAL_SECOND },
46 { "millisecond", UCAL_MILLISECOND },
47 { "zone_offset", UCAL_ZONE_OFFSET },
48 { "dst_offset", UCAL_DST_OFFSET },
49 { "year_woy", UCAL_YEAR_WOY },
50 { "dow_local", UCAL_DOW_LOCAL },
51 { "extended_year", UCAL_EXTENDED_YEAR },
52 { "julian_day", UCAL_JULIAN_DAY },
53 { "milliseconds_in_day", UCAL_MILLISECONDS_IN_DAY },
54 { "is_leap_month", UCAL_IS_LEAP_MONTH },
55 };
56
57 std::unordered_set<std::string> g_fieldsInFunctionAdd {
58 "year", "month", "date", "hour", "minute", "second", "millisecond",
59 "week_of_year", "week_of_month", "day_of_year", "day_of_week",
60 "day_of_week_in_month", "hour_of_day", "milliseconds_in_day",
61 };
62
63 std::unordered_map<std::string, CalendarType> g_typeMap {
64 { "buddhist", CalendarType::BUDDHIST },
65 { "chinese", CalendarType::CHINESE },
66 { "coptic", CalendarType::COPTIC },
67 { "ethiopic", CalendarType::ETHIOPIC },
68 { "hebrew", CalendarType::HEBREW },
69 { "gregory", CalendarType::GREGORY },
70 { "indian", CalendarType::INDIAN },
71 { "islamic_civil", CalendarType::ISLAMIC_CIVIL },
72 { "islamic_tbla", CalendarType::ISLAMIC_TBLA },
73 { "islamic_umalqura", CalendarType::ISLAMIC_UMALQURA },
74 { "japanese", CalendarType::JAPANESE },
75 { "persian", CalendarType::PERSIAN },
76 };
77 }
78
79 namespace OHOS {
80 namespace Global {
81 namespace I18n {
82 using namespace OHOS::FFI;
83
84 extern "C" {
GetCalendarType(const std::string & calendarType)85 CalendarType GetCalendarType(const std::string& calendarType)
86 {
87 CalendarType type = CalendarType::UNDEFINED;
88 if (g_typeMap.find(calendarType) != g_typeMap.end()) {
89 type = g_typeMap[calendarType];
90 }
91 return type;
92 }
93
FfiOHOSGetCalendar(const char * locale,const char * type)94 int64_t FfiOHOSGetCalendar(const char* locale, const char* type)
95 {
96 CalendarType calendarType = CalendarType::UNDEFINED;
97 if (type != nullptr) {
98 calendarType = GetCalendarType(std::string(type));
99 }
100 std::string localStr(locale);
101 auto nativeCalendar = FFIData::Create<CCalendar>(localStr, calendarType);
102 if (nativeCalendar == nullptr) {
103 HILOG_ERROR_I18N("Create CCalendar fail");
104 return -1;
105 }
106 return nativeCalendar->GetID();
107 }
108
FfiOHOSCalendarSetTime(int64_t id,double time)109 void FfiOHOSCalendarSetTime(int64_t id, double time)
110 {
111 auto instance = FFIData::GetData<CCalendar>(id);
112 if (!instance) {
113 HILOG_ERROR_I18N("The CCalendar instance is nullptr");
114 return;
115 }
116 instance->SetTime(time);
117 }
118
FfiOHOSCalendarSetDate(int64_t id,int32_t year,int32_t month,int32_t day)119 void FfiOHOSCalendarSetDate(int64_t id, int32_t year, int32_t month, int32_t day)
120 {
121 auto instance = FFIData::GetData<CCalendar>(id);
122 if (!instance) {
123 HILOG_ERROR_I18N("The CCalendar instance is nullptr");
124 return;
125 }
126 instance->Set(year, month, day);
127 }
128
FfiOHOSCalendarSetOfDay(int64_t id,int32_t hour,int32_t minute,int32_t second)129 void FfiOHOSCalendarSetOfDay(int64_t id, int32_t hour, int32_t minute, int32_t second)
130 {
131 auto instance = FFIData::GetData<CCalendar>(id);
132 if (!instance) {
133 HILOG_ERROR_I18N("The CCalendar instance is nullptr");
134 return;
135 }
136 std::time_t t = std::time(nullptr);
137 std::tm* now = std::localtime(&t);
138
139 int32_t currentHour = 0;
140 int32_t currentMinute = 0;
141 int32_t currentSecond = 0;
142
143 if (now != nullptr) {
144 currentHour = now->tm_hour;
145 currentMinute = now->tm_min;
146 currentSecond = now->tm_sec;
147 }
148
149 if (hour == -1) {
150 hour = currentHour;
151 }
152 if (minute == -1) {
153 minute = currentMinute;
154 }
155 if (second == -1) {
156 second = currentSecond;
157 }
158
159 instance->Set(UCalendarDateFields::UCAL_HOUR_OF_DAY, hour);
160 instance->Set(UCalendarDateFields::UCAL_MINUTE, minute);
161 instance->Set(UCalendarDateFields::UCAL_SECOND, second);
162 }
163
FfiOHOSCalendarSetTimeOfDay(int64_t id,int32_t hour,int32_t minute,int32_t second,uint32_t flag)164 void FfiOHOSCalendarSetTimeOfDay(int64_t id, int32_t hour, int32_t minute, int32_t second, uint32_t flag)
165 {
166 auto instance = FFIData::GetData<CCalendar>(id);
167 if (!instance) {
168 HILOG_ERROR_I18N("The CCalendar instance is nullptr");
169 return;
170 }
171 if (flag & HOUR_FLAG) {
172 instance->Set(UCalendarDateFields::UCAL_HOUR_OF_DAY, hour);
173 }
174 if (flag & MINUTE_FLAG) {
175 instance->Set(UCalendarDateFields::UCAL_MINUTE, minute);
176 }
177 if (flag & SECOND_FLAG) {
178 instance->Set(UCalendarDateFields::UCAL_SECOND, second);
179 }
180 }
181
FfiOHOSCalendarSetTimeZone(int64_t id,const char * timeZone)182 void FfiOHOSCalendarSetTimeZone(int64_t id, const char* timeZone)
183 {
184 auto instance = FFIData::GetData<CCalendar>(id);
185 if (!instance) {
186 HILOG_ERROR_I18N("The CCalendar instance is nullptr");
187 return;
188 }
189 instance->SetTimeZone(std::string(timeZone));
190 }
191
FfiOHOSCalendarGetTimeZone(int64_t id)192 char* FfiOHOSCalendarGetTimeZone(int64_t id)
193 {
194 auto instance = FFIData::GetData<CCalendar>(id);
195 if (!instance) {
196 HILOG_ERROR_I18N("The CCalendar instance is nullptr");
197 return nullptr;
198 }
199 std::string res = instance->GetTimeZone();
200 return MallocCString(res);
201 }
202
FfiOHOSCalendarSetFirstDayOfWeek(int64_t id,int32_t firstDayOfWeek)203 void FfiOHOSCalendarSetFirstDayOfWeek(int64_t id, int32_t firstDayOfWeek)
204 {
205 auto instance = FFIData::GetData<CCalendar>(id);
206 if (!instance) {
207 HILOG_ERROR_I18N("The CCalendar instance is nullptr");
208 return;
209 }
210 instance->SetFirstDayOfWeek(firstDayOfWeek);
211 }
212
FfiOHOSCalendarGetFirstDayOfWeek(int64_t id)213 int32_t FfiOHOSCalendarGetFirstDayOfWeek(int64_t id)
214 {
215 auto instance = FFIData::GetData<CCalendar>(id);
216 if (!instance) {
217 HILOG_ERROR_I18N("The CCalendar instance is nullptr");
218 return UCAL_SUNDAY;
219 }
220 return instance->GetFirstDayOfWeek();
221 }
222
FfiOHOSCalendarSetMinimalDaysInFirstWeek(int64_t id,int32_t minimalDays)223 void FfiOHOSCalendarSetMinimalDaysInFirstWeek(int64_t id, int32_t minimalDays)
224 {
225 auto instance = FFIData::GetData<CCalendar>(id);
226 if (!instance) {
227 HILOG_ERROR_I18N("The CCalendar instance is nullptr");
228 return;
229 }
230 instance->SetMinimalDaysInFirstWeek(minimalDays);
231 }
232
FfiOHOSCalendarGetMinimalDaysInFirstWeek(int64_t id)233 int32_t FfiOHOSCalendarGetMinimalDaysInFirstWeek(int64_t id)
234 {
235 auto instance = FFIData::GetData<CCalendar>(id);
236 if (!instance) {
237 HILOG_ERROR_I18N("The CCalendar instance is nullptr");
238 return 1;
239 }
240 return instance->GetMinimalDaysInFirstWeek();
241 }
242
FfiOHOSCalendarGet(int64_t id,char * field)243 int32_t FfiOHOSCalendarGet(int64_t id, char* field)
244 {
245 auto instance = FFIData::GetData<CCalendar>(id);
246 if (!instance) {
247 HILOG_ERROR_I18N("The CCalendar instance is nullptr");
248 return 0;
249 }
250 std::string fieldName(field);
251 return instance->Get(g_fieldsMap[fieldName]);
252 }
253
FfiOHOSCalendarGetDisplayName(int64_t id,char * locale)254 char* FfiOHOSCalendarGetDisplayName(int64_t id, char* locale)
255 {
256 std::string localeStr(locale);
257 auto instance = FFIData::GetData<CCalendar>(id);
258 if (!instance) {
259 HILOG_ERROR_I18N("The CCalendar instance is nullptr");
260 return nullptr;
261 }
262 std::string res = instance->GetDisplayName(localeStr);
263 return MallocCString(res);
264 }
265
FfiOHOSCalendarIsWeekend(int64_t id,CDate date)266 bool FfiOHOSCalendarIsWeekend(int64_t id, CDate date)
267 {
268 auto instance = FFIData::GetData<CCalendar>(id);
269 if (!instance) {
270 HILOG_ERROR_I18N("The CCalendar instance is nullptr");
271 return false;
272 }
273 // -1 indicates that the date is not provided
274 if (date.isNull) {
275 return instance->IsWeekend();
276 } else {
277 UErrorCode error = U_ZERO_ERROR;
278 return instance->IsWeekend(date.icuUdate, error);
279 }
280 }
281
FfiOHOSCalendarAdd(int64_t id,char * field,int32_t amount,int32_t * errcode)282 void FfiOHOSCalendarAdd(int64_t id, char* field, int32_t amount, int32_t* errcode)
283 {
284 auto instance = FFIData::GetData<CCalendar>(id);
285 if (!instance) {
286 HILOG_ERROR_I18N("The CCalendar instance is nullptr");
287 return;
288 }
289 std::string fieldStr(field);
290 if (g_fieldsInFunctionAdd.find(fieldStr) == g_fieldsInFunctionAdd.end()) {
291 *errcode = I18N_NOT_VALID;
292 }
293 instance->Add(g_fieldsMap[fieldStr], amount);
294 }
295
FfiOHOSCalendarGetTimeInMillis(int64_t id)296 double FfiOHOSCalendarGetTimeInMillis(int64_t id)
297 {
298 auto instance = FFIData::GetData<CCalendar>(id);
299 if (!instance) {
300 HILOG_ERROR_I18N("The CCalendar instance is nullptr");
301 return 0;
302 }
303 return instance->GetTimeInMillis();
304 }
305
FfiOHOSCalendarCompareDays(int64_t id,CDate date)306 int32_t FfiOHOSCalendarCompareDays(int64_t id, CDate date)
307 {
308 auto instance = FFIData::GetData<CCalendar>(id);
309 if (!instance) {
310 HILOG_ERROR_I18N("The CCalendar instance is nullptr");
311 return 0;
312 }
313 return instance->CompareDays(date.icuUdate);
314 }
315 }
316
317 } // namespace I18n
318 } // namespace Global
319 } // namespace OHOS
320