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