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