1 /* 2 * Copyright (c) 2025 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 #ifndef OHOS_GLOBAL_I18N_INTL_DATE_TIME_FORMAT_H 16 #define OHOS_GLOBAL_I18N_INTL_DATE_TIME_FORMAT_H 17 18 19 #include <map> 20 #include <string> 21 #include <unordered_map> 22 #include <vector> 23 #include "unicode/datefmt.h" 24 #include "unicode/dtitvfmt.h" 25 #include "unicode/dtptngen.h" 26 #include "unicode/localebuilder.h" 27 #include "unicode/locid.h" 28 #include "i18n_types.h" 29 30 namespace OHOS { 31 namespace Global { 32 namespace I18n { 33 class IcuPatternDesc { 34 public: 35 IcuPatternDesc(std::string property, const std::vector<std::pair<std::string, std::string>> &pairs, 36 std::vector<std::string> allowedValues); 37 38 virtual ~IcuPatternDesc() = default; 39 40 std::string property; 41 std::vector<std::pair<std::string, std::string>> pairs; 42 std::unordered_map<std::string, std::string> propertyValueToPattern; 43 std::vector<std::string> allowedValues; 44 }; 45 46 class Pattern { 47 public: 48 Pattern(const std::string& twoDigitPattern, const std::string& numericPattern); 49 virtual ~Pattern() = default; 50 51 std::vector<IcuPatternDesc> GetData() const; 52 static std::vector<IcuPatternDesc> GetIcuPatternDescs(); 53 54 private: 55 std::vector<IcuPatternDesc> data; 56 }; 57 58 struct CommonDateFormatPart { 59 int32_t fField = 0; 60 int32_t fBeginIndex = 0; 61 int32_t fEndIndex = 0; 62 int32_t index = 0; 63 bool isPreExist = false; 64 65 CommonDateFormatPart() = default; CommonDateFormatPartCommonDateFormatPart66 CommonDateFormatPart(int32_t fField, int32_t fBeginIndex, int32_t fEndIndex, int32_t index, bool isPreExist) 67 : fField(fField), fBeginIndex(fBeginIndex), fEndIndex(fEndIndex), index(index), isPreExist(isPreExist) 68 { 69 } 70 71 ~CommonDateFormatPart() = default; 72 }; 73 74 class IntlDateTimeFormat { 75 public: 76 IntlDateTimeFormat(const std::vector<std::string>& localeTags, 77 const std::unordered_map<std::string, std::string>& configs, std::string& errMessage); 78 virtual ~IntlDateTimeFormat(); 79 80 std::string Format(double milliseconds); 81 std::vector<std::pair<std::string, std::string>> FormatToParts(double milliseconds, std::string& errMessage); 82 std::string FormatRange(double start, double end, std::string& errMessage); 83 std::vector<std::pair<std::string, std::string>> FormatRangeToParts(double start, double end, 84 std::string& errMessage); 85 void ResolvedOptions(std::unordered_map<std::string, std::string>& configs); 86 static std::vector<std::string> SupportedLocalesOf(const std::vector<std::string>& requestLocales, 87 const std::map<std::string, std::string>& configs, I18nErrorCode& status); 88 89 static const std::string LOCALE_TAG; 90 static const std::string LOCALE_MATCHER_TAG; 91 static const std::string WEEK_DAY_TAG; 92 static const std::string ERA_TAG; 93 static const std::string YEAR_TAG; 94 static const std::string MONTH_TAG; 95 static const std::string DAY_TAG; 96 static const std::string HOUR_TAG; 97 static const std::string MINUTE_TAG; 98 static const std::string SECOND_TAG; 99 static const std::string TIME_ZONE_NAME_TAG; 100 static const std::string FORMAT_MATCHER_TAG; 101 static const std::string HOUR12_TAG; 102 static const std::string TIME_ZONE_TAG; 103 static const std::string CALENDAR_TAG; 104 static const std::string DAY_PERIOD_TAG; 105 static const std::string NUMBERING_SYSTEM_TAG; 106 static const std::string DATE_STYLE_TAG; 107 static const std::string TIME_STYLE_TAG; 108 static const std::string HOUR_CYCLE_TAG; 109 static const std::string FRACTIONAL_SECOND_DIGITS_TAG; 110 111 private: 112 bool ParseConfigs(const std::unordered_map<std::string, std::string>& configs, 113 std::string& errMessage); 114 void InitIcuLocale(); 115 bool InitIntlDateTimeFormat(const std::unordered_map<std::string, std::string>& configs, std::string& errMessage); 116 bool InitIcuTimeZone(const std::unordered_map<std::string, std::string>& configs, std::string& errMessage); 117 bool InitDateTimePatternGenerator(std::string& errMessage); 118 bool InitHourCycle(std::string& effectiveHourCycle); 119 int32_t GetFractionalSecondDigit(const std::unordered_map<std::string, std::string>& configs); 120 bool InitSkeleton(const std::unordered_map<std::string, std::string>& configs, 121 const std::string& effectiveHourCycle, bool& isHourDefined, bool& isExistComponents, std::string& errMessage); 122 bool InitDateTimeStyle(const std::unordered_map<std::string, std::string>& configs, 123 const std::string& effectiveHourCycle, bool isHourDefined, std::string& errMessage); 124 void InitDateTimeSkeleton(const std::vector<std::string> &options, std::string &skeleton, const std::string& hc); 125 bool InitIcuSimpleDateFormat(bool isExistComponents, std::string& errMessage); 126 std::unique_ptr<icu::SimpleDateFormat> GetSimpleDateFormatFromStyle(); 127 bool InitIcuCalendar(); 128 bool InitDateIntervalFormat(); 129 void ResolvedCalendarAndTimeZone(std::unordered_map<std::string, std::string>& configs); 130 void ResolvedDateTimeStyle(std::unordered_map<std::string, std::string>& configs); 131 132 static std::vector<IcuPatternDesc> GetIcuPatternDesc(const std::string& effectiveHourCycle); 133 static icu::DateFormat::EStyle GetEStyleFromDateTimeStyle(const std::string& style); 134 static std::string GetHourCycleFromPattern(const icu::UnicodeString& pattern); 135 static icu::UnicodeString ChangeHourCyclePattern(const icu::UnicodeString& pattern, const std::string& hc); 136 static icu::UnicodeString ReplaceHourCycleOfSkeleton(const icu::UnicodeString& skeleton, 137 const std::string& hc); 138 static std::string ConvertUDateFormatHourCycleToString(UDateFormatHourCycle hc); 139 static std::string ConvertFieldIdToDateType(int32_t fieldId); 140 static std::vector<CommonDateFormatPart> CreateDateIntervalParts(const icu::FormattedDateInterval& formatted, 141 icu::UnicodeString& formattedParts, std::string& errMessage); 142 static bool IsValidTimeZoneName(const icu::TimeZone &tz); 143 144 std::string localeMatcher = "best fit"; 145 std::string weekday; 146 std::string era; 147 std::string year; 148 std::string month; 149 std::string day; 150 std::string hour; 151 std::string minute; 152 std::string second; 153 std::string timeZoneName; 154 std::string formatMatcher = "best fit"; 155 std::string hour12; 156 std::string timeZone; 157 std::string calendar; 158 std::string dayPeriod; 159 std::string numberingSystem; 160 std::string dateStyle; 161 std::string timeStyle; 162 std::string hourCycle; 163 std::string fractionalSecondDigits; 164 std::string localeString; 165 std::vector<std::string> skeletonOpts; 166 bool initSuccess = false; 167 bool isIso8601 = false; 168 std::string skeleton; 169 icu::Locale icuLocale; 170 icu::DateTimePatternGenerator* icuDateTimePatternGenerator = nullptr; 171 icu::TimeZone* icuTimeZone = nullptr; 172 icu::Calendar* icuCalendar = nullptr; 173 std::unique_ptr<icu::SimpleDateFormat> icuSimpleDateFormat = nullptr; 174 icu::DateIntervalFormat* dateIntervalFormat = nullptr; 175 static bool icuInitialized; 176 static bool Init(); 177 }; 178 } // namespace I18n 179 } // namespace Global 180 } // namespace OHOS 181 #endif