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 
16 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_PICKER_PICKER_DATA_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_PICKER_PICKER_DATA_H
18 
19 #include "base/utils/utils.h"
20 
21 
22 namespace OHOS::Ace {
23 
24 enum DatePickerType {
25     TIME = 0,
26     DATE,
27 };
28 
29 class ACE_FORCE_EXPORT PickerDate final {
30 public:
31     PickerDate() = default;
PickerDate(uint32_t year,uint32_t month,uint32_t day)32     PickerDate(uint32_t year, uint32_t month, uint32_t day) : year_(year), month_(month), day_(day) {}
33 
34     ~PickerDate() = default;
35 
36     static PickerDate Current();
37 
38     static uint32_t GetMaxDay(uint32_t year, uint32_t month);
39 
40     static bool IsLeapYear(uint32_t year);
41 
GetYear()42     uint32_t GetYear() const
43     {
44         return year_;
45     }
SetYear(uint32_t value)46     void SetYear(uint32_t value)
47     {
48         year_ = value;
49     }
50 
GetMonth()51     uint32_t GetMonth() const
52     {
53         return month_;
54     }
SetMonth(uint32_t value)55     void SetMonth(uint32_t value)
56     {
57         month_ = value;
58     }
59 
GetDay()60     uint32_t GetDay() const
61     {
62         return day_;
63     }
SetDay(uint32_t value)64     void SetDay(uint32_t value)
65     {
66         day_ = value;
67     }
68 
GetWeek()69     uint32_t GetWeek() const
70     {
71         return week_;
72     }
SetWeek(uint32_t value)73     void SetWeek(uint32_t value)
74     {
75         week_ = value;
76     }
77 
78     std::string ToString(bool jsonFormat, int32_t status = -1) const;
79 
80     uint32_t ToDays() const;
81     void FromDays(uint32_t days);
82 
83 private:
84     uint32_t year_ = 0;
85     uint32_t month_ = 0;
86     uint32_t day_ = 0;
87     uint32_t week_ = 0;
88 };
89 
90 class PickerTime final {
91 public:
92     PickerTime() = default;
PickerTime(uint32_t hour,uint32_t minute,uint32_t second)93     PickerTime(uint32_t hour, uint32_t minute, uint32_t second) : hour_(hour), minute_(minute), second_(second) {}
94 
95     ~PickerTime() = default;
96 
97     static PickerTime Current();
98 
GetHour()99     uint32_t GetHour() const
100     {
101         return hour_;
102     }
SetHour(uint32_t value)103     void SetHour(uint32_t value)
104     {
105         hour_ = value;
106     }
107 
GetMinute()108     uint32_t GetMinute() const
109     {
110         return minute_;
111     }
SetMinute(uint32_t value)112     void SetMinute(uint32_t value)
113     {
114         minute_ = value;
115     }
116 
GetSecond()117     uint32_t GetSecond() const
118     {
119         return second_;
120     }
SetSecond(uint32_t value)121     void SetSecond(uint32_t value)
122     {
123         second_ = value;
124     }
125 
126     std::string ToString(bool jsonFormat, bool hasSecond, int32_t status = -1) const;
127 
128 private:
129     uint32_t hour_ = 0;
130     uint32_t minute_ = 0;
131     uint32_t second_ = 0;
132 };
133 
134 class PickerDateTime final {
135 public:
136     PickerDateTime() = default;
PickerDateTime(const PickerDate & date,const PickerTime & time)137     PickerDateTime(const PickerDate& date, const PickerTime& time) : date_(date), time_(time) {}
138 
139     ~PickerDateTime() = default;
140 
141     static PickerDateTime Current();
142 
GetDate()143     const PickerDate& GetDate() const
144     {
145         return date_;
146     }
SetDate(const PickerDate & value)147     void SetDate(const PickerDate& value)
148     {
149         date_ = value;
150     }
151 
GetTime()152     const PickerTime& GetTime() const
153     {
154         return time_;
155     }
SetTime(const PickerTime & value)156     void SetTime(const PickerTime& value)
157     {
158         time_ = value;
159     }
160 
161     std::string ToString(bool jsonFormat, int32_t status = -1) const;
162 
163 private:
164     PickerDate date_;
165     PickerTime time_;
166 };
167 
168 class LunarCalculator {
169 public:
GetLunarLeapMonth(uint32_t lunarYear)170     static uint32_t GetLunarLeapMonth(uint32_t lunarYear)
171     {
172         if (lunarYear >= YEAR_START + LUNAR_INFO_SIZE) {
173             return 0;
174         }
175         uint32_t leapMonth = LUNAR_INFO[lunarYear - YEAR_START] & 0xf; // use 0xf to get leap month info
176         return leapMonth == 0xf ? 0 : leapMonth;
177     }
178 
GetLunarLeapDays(uint32_t lunarYear)179     static uint32_t GetLunarLeapDays(uint32_t lunarYear)
180     {
181         if (lunarYear >= YEAR_START - 1 + LUNAR_INFO_SIZE) {
182             return 0;
183         }
184         return GetLunarLeapMonth(lunarYear) > 0 ? ((LUNAR_INFO[lunarYear - YEAR_START + 1] & 0xf) == 0xf ? 30 : 29)
185                                                 : 0; // big month 30 days other 29
186     }
187 
GetLunarYearDays(uint32_t lunarYear)188     static uint32_t GetLunarYearDays(uint32_t lunarYear)
189     {
190         if (lunarYear >= YEAR_START + LUNAR_INFO_SIZE) {
191             return 0;
192         }
193         uint32_t totalDays = 348;                          // lunar year has (12 * 29 =) 348 days at least
194         for (uint32_t i = 0x8000; i > 0x8; i >>= 1) { // get month info from bit of LUNAR_INFO
195             totalDays += ((LUNAR_INFO[lunarYear - YEAR_START] & i) != 0) ? 1 : 0;
196         }
197 
198         return totalDays + GetLunarLeapDays(lunarYear);
199     }
200 
GetLunarMonthDays(uint32_t lunarYear,uint32_t lunarMonth)201     static uint32_t GetLunarMonthDays(uint32_t lunarYear, uint32_t lunarMonth)
202     {
203         if (lunarYear >= YEAR_START + LUNAR_INFO_SIZE) {
204             return 0;
205         }
206         uint32_t month = static_cast<uint32_t>(lunarMonth);
207         // big month 30 days other 29
208         return ((LUNAR_INFO[lunarYear - YEAR_START] & (0x10000u >> (month % MAX_MONTH))) != 0) ? 30 : 29;
209     }
210 
211 private:
212     static constexpr uint32_t YEAR_START = 1897; // start year reference with LUNAR_INFO
213     static constexpr int32_t LUNAR_INFO_SIZE = 207;
214     static constexpr uint32_t MAX_MONTH = 13;
215     static const uint16_t LUNAR_INFO[];
216 };
217 
218 class PickerStringFormatter {
219 public:
220     static const std::string& GetYear(uint32_t year);
221 
222     static const std::string& GetSolarMonth(uint32_t month);
223 
224     static const std::string& GetSolarDay(uint32_t day);
225 
226     static const std::string& GetLunarMonth(uint32_t month, bool isLeap);
227 
228     static const std::string& GetLunarDay(uint32_t day);
229 
230     static const std::vector<std::string>& GetTagOrder();
231 
232 private:
233     static void Init();
234 
235     static bool inited_;
236 
237     static const std::string empty_;
238 
239     static std::vector<std::string> years_; // year from 1900 to 2100,count is 201
240 
241     static std::vector<std::string> solarMonths_; // solar month from 1 to 12,count is 12
242     static std::vector<std::string> solarDays_; // solar day from 1 to 31, count is 31
243 
244     static std::vector<std::string> lunarMonths_; // lunar month from 1 to 24, count is 24
245     static std::vector<std::string> lunarDays_; // lunar day from 1 to 30, count is 30
246     static std::vector<std::string> tagOrder_; // year month day tag order
247 };
248 
249 class PickerDateF {
250 public:
251     std::optional<uint32_t> year;
252     std::optional<uint32_t> month;
253     std::optional<uint32_t> day;
254     bool lunar = false;
255     bool leap = false;
256 
257     PickerDateF() = default;
258     ~PickerDateF() = default;
259 
CreateYear(uint32_t year)260     static PickerDateF CreateYear(uint32_t year)
261     {
262         PickerDateF date;
263         date.year = year;
264         return date;
265     }
266 
267     static PickerDateF CreateMonth(uint32_t month, bool lunar = false, bool leap = false)
268     {
269         PickerDateF date;
270         date.month = month;
271         date.lunar = lunar;
272         date.leap = leap;
273         return date;
274     }
275 
276     static PickerDateF CreateDay(uint32_t day, bool lunar = false)
277     {
278         PickerDateF date;
279         date.day = day;
280         date.lunar = lunar;
281         return date;
282     }
283 
284     static PickerDateF CreateMonthDay(uint32_t month, uint32_t day, bool lunar = false, bool leap = false)
285     {
286         PickerDateF date;
287         date.month = month;
288         date.day = day;
289         date.lunar = lunar;
290         date.leap = leap;
291         return date;
292     }
293 };
294 
295 } // namespace OHOS::Ace
296 
297 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_PICKER_PICKER_DATA_H
298