• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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