• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "date_time_format.h"
16 #include "locale_config.h"
17 #include "ohos/init_data.h"
18 #include "utils.h"
19 
20 namespace OHOS {
21 namespace Global {
22 namespace I18n {
23 const char *DateTimeFormat::TIMEZONE_KEY = "persist.time.timezone";
24 const char *DateTimeFormat::DEFAULT_TIMEZONE = "GMT";
25 
26 using namespace icu;
27 bool DateTimeFormat::icuInitialized = DateTimeFormat::Init();
28 
29 std::map<std::string, DateFormat::EStyle> DateTimeFormat::dateTimeStyle = {
30     { "full", DateFormat::EStyle::kFull },
31     { "long", DateFormat::EStyle::kLong },
32     { "medium", DateFormat::EStyle::kMedium },
33     { "short", DateFormat::EStyle::kShort }
34 };
35 
DateTimeFormat(const std::vector<std::string> & localeTags,std::map<std::string,std::string> & configs)36 DateTimeFormat::DateTimeFormat(const std::vector<std::string> &localeTags, std::map<std::string, std::string> &configs)
37 {
38     UErrorCode status = U_ZERO_ERROR;
39     ParseConfigsPartOne(configs);
40     ParseConfigsPartTwo(configs);
41     for (size_t i = 0; i < localeTags.size(); i++) {
42         std::string curLocale = localeTags[i];
43         locale = Locale::forLanguageTag(StringPiece(curLocale), status);
44         if (status != U_ZERO_ERROR) {
45             status = U_ZERO_ERROR;
46             continue;
47         }
48         if (LocaleInfo::allValidLocales.count(locale.getLanguage()) > 0) {
49             createSuccess = InitWithLocale(curLocale, configs);
50             if (!createSuccess || !dateFormat) {
51                 FreeDateTimeFormat();
52                 continue;
53             }
54             break;
55         }
56     }
57     if (!localeInfo || !dateFormat) {
58         createSuccess = InitWithDefaultLocale(configs);
59     }
60 }
61 
FreeDateTimeFormat()62 void DateTimeFormat::FreeDateTimeFormat()
63 {
64     if (dateIntvFormat != nullptr) {
65         delete dateIntvFormat;
66         dateIntvFormat = nullptr;
67     }
68     if (calendar != nullptr) {
69         delete calendar;
70         calendar = nullptr;
71     }
72     if (dateFormat != nullptr) {
73         delete dateFormat;
74         dateFormat = nullptr;
75     }
76     if (localeInfo != nullptr) {
77         delete localeInfo;
78         localeInfo = nullptr;
79     }
80 }
81 
~DateTimeFormat()82 DateTimeFormat::~DateTimeFormat()
83 {
84     FreeDateTimeFormat();
85 }
86 
CheckInitSuccess()87 bool DateTimeFormat::CheckInitSuccess()
88 {
89     if (dateIntvFormat == nullptr || calendar == nullptr || dateFormat == nullptr || localeInfo == nullptr) {
90         return false;
91     }
92     return true;
93 }
94 
CreateInstance(const std::vector<std::string> & localeTags,std::map<std::string,std::string> & configs)95 std::unique_ptr<DateTimeFormat> DateTimeFormat::CreateInstance(const std::vector<std::string> &localeTags,
96                                                                std::map<std::string, std::string> &configs)
97 {
98     std::unique_ptr<DateTimeFormat> dateTimeFormat = std::make_unique<DateTimeFormat>(localeTags, configs);
99     if (!dateTimeFormat->CheckInitSuccess()) {
100         return nullptr;
101     }
102     return dateTimeFormat;
103 }
104 
InitWithLocale(const std::string & curLocale,std::map<std::string,std::string> & configs)105 bool DateTimeFormat::InitWithLocale(const std::string &curLocale, std::map<std::string, std::string> &configs)
106 {
107     localeInfo = new LocaleInfo(curLocale, configs);
108     if (localeInfo == nullptr || !localeInfo->InitSuccess()) {
109         return false;
110     }
111     locale = localeInfo->GetLocale();
112     localeTag = localeInfo->GetBaseName();
113     if (hourCycle.empty()) {
114         hourCycle = localeInfo->GetHourCycle();
115     }
116     if (hour12.empty() && hourCycle.empty()) {
117         bool is24HourClock = LocaleConfig::Is24HourClock();
118         if (is24HourClock) {
119             hour12 = "false";
120         }
121     }
122     ComputeHourCycleChars();
123     ComputeSkeleton();
124     UErrorCode status = U_ZERO_ERROR;
125     if (!configs.size()) {
126         InitDateFormatWithoutConfigs(status);
127     } else {
128         InitDateFormat(status);
129     }
130     if (!U_SUCCESS(status)) {
131         return false;
132     }
133     status = U_ZERO_ERROR;
134     calendar = Calendar::createInstance(locale, status);
135     if (!U_SUCCESS(status)) {
136         return false;
137     }
138     return true;
139 }
140 
InitWithDefaultLocale(std::map<std::string,std::string> & configs)141 bool DateTimeFormat::InitWithDefaultLocale(std::map<std::string, std::string> &configs)
142 {
143     if (localeInfo != nullptr) {
144         delete localeInfo;
145         localeInfo = nullptr;
146     }
147     if (dateFormat != nullptr) {
148         delete dateFormat;
149         dateFormat = nullptr;
150     }
151     return InitWithLocale(LocaleConfig::GetSystemLocale(), configs);
152 }
153 
InitDateFormatWithoutConfigs(UErrorCode & status)154 void DateTimeFormat::InitDateFormatWithoutConfigs(UErrorCode &status)
155 {
156     dateFormat = DateFormat::createDateInstance(DateFormat::SHORT, locale);
157     SimpleDateFormat *simDateFormat = static_cast<SimpleDateFormat*>(dateFormat);
158     if (simDateFormat != nullptr) {
159         simDateFormat->toPattern(pattern);
160     }
161     dateIntvFormat = DateIntervalFormat::createInstance(pattern, locale, status);
162 }
163 
FixPatternPartOne()164 void DateTimeFormat::FixPatternPartOne()
165 {
166     if (hour12 == "true") {
167         pattern.findAndReplace(icu::UnicodeString::fromUTF8(StringPiece("H")),
168             icu::UnicodeString::fromUTF8(StringPiece("h")));
169         pattern.findAndReplace(icu::UnicodeString::fromUTF8(StringPiece("k")),
170             icu::UnicodeString::fromUTF8(StringPiece("h")));
171         pattern.findAndReplace(icu::UnicodeString::fromUTF8(StringPiece("K")),
172             icu::UnicodeString::fromUTF8(StringPiece("h")));
173     } else if (hour12 == "false") {
174         pattern.findAndReplace(icu::UnicodeString::fromUTF8(StringPiece("h")),
175             icu::UnicodeString::fromUTF8(StringPiece("H")));
176         pattern.findAndReplace(icu::UnicodeString::fromUTF8(StringPiece("k")),
177             icu::UnicodeString::fromUTF8(StringPiece("H")));
178         pattern.findAndReplace(icu::UnicodeString::fromUTF8(StringPiece("K")),
179             icu::UnicodeString::fromUTF8(StringPiece("H")));
180         RemoveAmPmChar();
181     } else if (hourCycle != "") {
182         FixPatternPartTwo();
183     }
184 }
185 
FixPatternPartTwo()186 void DateTimeFormat::FixPatternPartTwo()
187 {
188     if (hourCycle == "h11") {
189         pattern.findAndReplace(icu::UnicodeString::fromUTF8(StringPiece("h")),
190             icu::UnicodeString::fromUTF8(StringPiece("k")));
191         pattern.findAndReplace(icu::UnicodeString::fromUTF8(StringPiece("H")),
192             icu::UnicodeString::fromUTF8(StringPiece("k")));
193         pattern.findAndReplace(icu::UnicodeString::fromUTF8(StringPiece("K")),
194             icu::UnicodeString::fromUTF8(StringPiece("k")));
195     } else if (hourCycle == "h12") {
196         pattern.findAndReplace(icu::UnicodeString::fromUTF8(StringPiece("H")),
197             icu::UnicodeString::fromUTF8(StringPiece("h")));
198         pattern.findAndReplace(icu::UnicodeString::fromUTF8(StringPiece("k")),
199             icu::UnicodeString::fromUTF8(StringPiece("h")));
200         pattern.findAndReplace(icu::UnicodeString::fromUTF8(StringPiece("K")),
201             icu::UnicodeString::fromUTF8(StringPiece("h")));
202     } else if (hourCycle == "h23") {
203         pattern.findAndReplace(icu::UnicodeString::fromUTF8(StringPiece("h")),
204             icu::UnicodeString::fromUTF8(StringPiece("K")));
205         pattern.findAndReplace(icu::UnicodeString::fromUTF8(StringPiece("H")),
206             icu::UnicodeString::fromUTF8(StringPiece("K")));
207         pattern.findAndReplace(icu::UnicodeString::fromUTF8(StringPiece("k")),
208             icu::UnicodeString::fromUTF8(StringPiece("K")));
209         RemoveAmPmChar();
210     } else if (hourCycle == "h24") {
211         pattern.findAndReplace(icu::UnicodeString::fromUTF8(StringPiece("h")),
212             icu::UnicodeString::fromUTF8(StringPiece("H")));
213         pattern.findAndReplace(icu::UnicodeString::fromUTF8(StringPiece("k")),
214             icu::UnicodeString::fromUTF8(StringPiece("H")));
215         pattern.findAndReplace(icu::UnicodeString::fromUTF8(StringPiece("K")),
216             icu::UnicodeString::fromUTF8(StringPiece("H")));
217         RemoveAmPmChar();
218     }
219 }
220 
RemoveAmPmChar()221 void DateTimeFormat::RemoveAmPmChar()
222 {
223     std::string patternString = "";
224     pattern.toUTF8String(patternString);
225     size_t amPmCharStartIdx = 0;
226     size_t amPmCharEndIdx = 0;
227     for (size_t i = 0; i < patternString.length(); i++) {
228         if (patternString[i] != 'a') {
229             continue;
230         }
231         if ((i + 1) < patternString.length() && patternString[i + 1] == 't') {
232             continue;
233         }
234         if (!i) {
235             amPmCharStartIdx = i;
236         } else {
237             amPmCharStartIdx = i - 1;
238             while (amPmCharStartIdx > 0 && patternString[amPmCharStartIdx] == ' ') {
239                 amPmCharStartIdx -= 1;
240             }
241             if (amPmCharStartIdx || patternString[amPmCharStartIdx] != ' ') {
242                 amPmCharStartIdx += 1;
243             }
244         }
245         amPmCharEndIdx = i + 1;
246         while (amPmCharEndIdx < patternString.length() && patternString[amPmCharEndIdx] == ' ') {
247             amPmCharEndIdx += 1;
248         }
249         break;
250     }
251     size_t length = amPmCharEndIdx - amPmCharStartIdx;
252     if (length) {
253         if (!amPmCharStartIdx || amPmCharEndIdx == patternString.length()) {
254             patternString = patternString.replace(amPmCharStartIdx, length, "");
255         } else {
256             patternString = patternString.replace(amPmCharStartIdx, length, " ");
257         }
258         pattern = icu::UnicodeString(patternString.data(), patternString.length());
259     }
260 }
261 
InitDateFormat(UErrorCode & status)262 void DateTimeFormat::InitDateFormat(UErrorCode &status)
263 {
264     if (!dateStyle.empty() || !timeStyle.empty()) {
265         DateFormat::EStyle dateStyleValue = DateFormat::EStyle::kNone;
266         DateFormat::EStyle timeStyleValue = DateFormat::EStyle::kNone;
267         if (!dateStyle.empty() && dateTimeStyle.count(dateStyle) > 0) {
268             dateStyleValue = dateTimeStyle[dateStyle];
269         }
270         if (!timeStyle.empty() && dateTimeStyle.count(timeStyle) > 0) {
271             timeStyleValue = dateTimeStyle[timeStyle];
272         }
273         dateFormat = DateFormat::createDateTimeInstance(dateStyleValue, timeStyleValue, locale);
274         SimpleDateFormat *simDateFormat = static_cast<SimpleDateFormat*>(dateFormat);
275         if (simDateFormat != nullptr) {
276             simDateFormat->toPattern(pattern);
277         }
278         FixPatternPartOne();
279         delete dateFormat;
280         dateFormat = new SimpleDateFormat(pattern, locale, status);
281         if (!U_SUCCESS(status)) {
282             return;
283         }
284     } else {
285         auto patternGenerator =
286             std::unique_ptr<DateTimePatternGenerator>(DateTimePatternGenerator::createInstance(locale, status));
287         if (!U_SUCCESS(status)) {
288             return;
289         }
290         ComputePattern();
291         pattern =
292             patternGenerator->replaceFieldTypes(patternGenerator->getBestPattern(pattern, status), pattern, status);
293         pattern = patternGenerator->getBestPattern(pattern, status);
294         status = U_ZERO_ERROR;
295         dateFormat = new SimpleDateFormat(pattern, locale, status);
296         if (!U_SUCCESS(status)) {
297             return;
298         }
299     }
300     status = U_ZERO_ERROR;
301     dateIntvFormat = DateIntervalFormat::createInstance(pattern, locale, status);
302 }
303 
ParseConfigsPartOne(std::map<std::string,std::string> & configs)304 void DateTimeFormat::ParseConfigsPartOne(std::map<std::string, std::string> &configs)
305 {
306     if (configs.count("dateStyle") > 0) {
307         dateStyle = configs["dateStyle"];
308     }
309     if (configs.count("timeStyle") > 0) {
310         timeStyle = configs["timeStyle"];
311     }
312     if (configs.count("year") > 0) {
313         year = configs["year"];
314     }
315     if (configs.count("month") > 0) {
316         month = configs["month"];
317     }
318     if (configs.count("day") > 0) {
319         day = configs["day"];
320     }
321     if (configs.count("hour") > 0) {
322         hour = configs["hour"];
323     }
324     if (configs.count("minute") > 0) {
325         minute = configs["minute"];
326     }
327     if (configs.count("second") > 0) {
328         second = configs["second"];
329     }
330 }
331 
ParseConfigsPartTwo(std::map<std::string,std::string> & configs)332 void DateTimeFormat::ParseConfigsPartTwo(std::map<std::string, std::string> &configs)
333 {
334     if (configs.count("hourCycle") > 0) {
335         hourCycle = configs["hourCycle"];
336     }
337     if (configs.count("timeZone") > 0) {
338         timeZone = configs["timeZone"];
339     }
340     if (configs.count("numberingSystem") > 0) {
341         numberingSystem = configs["numberingSystem"];
342     }
343     if (configs.count("hour12") > 0) {
344         hour12 = configs["hour12"];
345     }
346     if (configs.count("weekday") > 0) {
347         weekday = configs["weekday"];
348     }
349     if (configs.count("era") > 0) {
350         era = configs["era"];
351     }
352     if (configs.count("timeZoneName") > 0) {
353         timeZoneName = configs["timeZoneName"];
354     }
355     if (configs.count("dayPeriod") > 0) {
356         dayPeriod = configs["dayPeriod"];
357     }
358     if (configs.count("localeMatcher") > 0) {
359         localeMatcher = configs["localeMatcher"];
360     }
361     if (configs.count("formatMatcher") > 0) {
362         formatMatcher = configs["formatMatcher"];
363     }
364 }
365 
ComputeSkeleton()366 void DateTimeFormat::ComputeSkeleton()
367 {
368     if (year.empty() && month.empty() && day.empty() && hour.empty() && minute.empty() && second.empty() &&
369         weekday.empty()) {
370         pattern.append("yMd");
371     }
372     AddOptions(year, yearChar);
373     AddOptions(month, monthChar);
374     AddOptions(day, dayChar);
375     AddOptions(hour, hourChar);
376     AddOptions(minute, minuteChar);
377     AddOptions(second, secondChar);
378     if ((hourCycle == "h12" || hourCycle == "h11" || hour12 == "true") && !hour.empty()) {
379         pattern.append(amPmChar);
380     }
381     AddOptions(timeZoneName, timeZoneChar);
382     AddOptions(weekday, weekdayChar);
383     AddOptions(era, eraChar);
384 }
385 
AddOptions(std::string option,char16_t optionChar)386 void DateTimeFormat::AddOptions(std::string option, char16_t optionChar)
387 {
388     if (!option.empty()) {
389         pattern.append(optionChar);
390     }
391 }
392 
ComputeHourCycleChars()393 void DateTimeFormat::ComputeHourCycleChars()
394 {
395     if (!hour12.empty()) {
396         if (hour12 == "true") {
397             hourNumericString = "h";
398             hourTwoDigitString = "hh";
399         } else {
400             hourNumericString = "H";
401             hourTwoDigitString = "HH";
402         }
403     } else {
404         if (hourCycle == "h11") {
405             hourNumericString = "K";
406             hourTwoDigitString = "KK";
407         } else if (hourCycle == "h12") {
408             hourNumericString = "h";
409             hourTwoDigitString = "hh";
410         } else if (hourCycle == "h23") {
411             hourNumericString = "H";
412             hourTwoDigitString = "HH";
413         } else if (hourCycle == "h24") {
414             hourNumericString = "k";
415             hourTwoDigitString = "kk";
416         }
417     }
418 }
419 
ComputePattern()420 void DateTimeFormat::ComputePattern()
421 {
422     ComputePartOfPattern(year, yearChar, "yy", "yyyy");
423     ComputePartOfPattern(day, dayChar, "dd", "d");
424     ComputePartOfPattern(hour, hourChar, hourTwoDigitString, hourNumericString);
425     ComputePartOfPattern(minute, minuteChar, "mm", "mm");
426     ComputePartOfPattern(second, secondChar, "ss", "ss");
427     if (!month.empty()) {
428         UnicodeString monthOfPattern = UnicodeString(monthChar);
429         int32_t length = monthOfPattern.length();
430         if (month == "numeric" && length != NUMERIC_LENGTH) {
431             pattern.findAndReplace(monthOfPattern, UnicodeString::fromUTF8(StringPiece("M")));
432         } else if (month == "2-digit" && length != TWO_DIGIT_LENGTH) {
433             pattern.findAndReplace(monthOfPattern, UnicodeString::fromUTF8(StringPiece("MM")));
434         } else if (month == "long" && length != LONG_LENGTH) {
435             pattern.findAndReplace(monthOfPattern, UnicodeString::fromUTF8(StringPiece("MMMM")));
436         } else if (month == "short" && length != SHORT_LENGTH) {
437             pattern.findAndReplace(monthOfPattern, UnicodeString::fromUTF8(StringPiece("MMM")));
438         } else if (month == "narrow" && length != NARROW_LENGTH) {
439             pattern.findAndReplace(monthOfPattern, UnicodeString::fromUTF8(StringPiece("MMMMM")));
440         }
441     }
442     if (!timeZoneName.empty()) {
443         UnicodeString timeZoneOfPattern = UnicodeString(timeZoneChar);
444         if (timeZoneName == "long") {
445             pattern.findAndReplace(timeZoneOfPattern, UnicodeString::fromUTF8(StringPiece("zzzz")));
446         } else if (timeZoneName == "short") {
447             pattern.findAndReplace(timeZoneOfPattern, UnicodeString::fromUTF8(StringPiece("O")));
448         }
449     }
450 
451     ComputeWeekdayOrEraOfPattern(weekday, weekdayChar, "EEEE", "E", "EEEEE");
452     ComputeWeekdayOrEraOfPattern(era, eraChar, "GGGG", "G", "GGGGG");
453 }
454 
ComputePartOfPattern(std::string option,char16_t character,std::string twoDigitChar,std::string numericChar)455 void DateTimeFormat::ComputePartOfPattern(std::string option, char16_t character, std::string twoDigitChar,
456     std::string numericChar)
457 {
458     if (!option.empty()) {
459         UnicodeString curPartOfPattern = UnicodeString(character);
460         if (option == "2-digit") {
461             pattern.findAndReplace(curPartOfPattern, UnicodeString::fromUTF8(StringPiece(twoDigitChar)));
462         } else if (option == "numeric") {
463             pattern.findAndReplace(curPartOfPattern, UnicodeString::fromUTF8(StringPiece(numericChar)));
464         }
465     }
466 }
467 
ComputeWeekdayOrEraOfPattern(std::string option,char16_t character,std::string longChar,std::string shortChar,std::string narrowChar)468 void DateTimeFormat::ComputeWeekdayOrEraOfPattern(std::string option, char16_t character, std::string longChar,
469     std::string shortChar, std::string narrowChar)
470 {
471     if (!option.empty()) {
472         UnicodeString curPartOfPattern = UnicodeString(character);
473         int32_t length = curPartOfPattern.length();
474         if (option == "long" && length != LONG_ERA_LENGTH) {
475             pattern.findAndReplace(curPartOfPattern, UnicodeString::fromUTF8(StringPiece(longChar)));
476         } else if (option == "short" && length != SHORT_ERA_LENGTH) {
477             pattern.findAndReplace(curPartOfPattern, UnicodeString::fromUTF8(StringPiece(shortChar)));
478         } else if (option == "narrow" && length != NARROW_LENGTH) {
479             pattern.findAndReplace(curPartOfPattern, UnicodeString::fromUTF8(StringPiece(narrowChar)));
480         }
481     }
482 }
483 
GetArrayValue(int64_t * dateArray,size_t index,size_t size)484 int64_t DateTimeFormat::GetArrayValue(int64_t *dateArray, size_t index, size_t size)
485 {
486     if (index < size) {
487         return dateArray[index];
488     } else {
489         return 0;
490     }
491 }
492 
GetSystemTimezone()493 std::string DateTimeFormat::GetSystemTimezone()
494 {
495     std::string systemTimezone = ReadSystemParameter(TIMEZONE_KEY, SYS_PARAM_LEN);
496     if (systemTimezone.length() == 0) {
497         systemTimezone = DEFAULT_TIMEZONE;
498     }
499     return systemTimezone;
500 }
501 
Format(int64_t milliseconds)502 std::string DateTimeFormat::Format(int64_t milliseconds)
503 {
504     if (!createSuccess) {
505         return "";
506     }
507     UErrorCode status = U_ZERO_ERROR;
508     std::string result;
509     UnicodeString dateString;
510     calendar->clear();
511     std::string timezoneStr = timeZone.empty() ? GetSystemTimezone() : timeZone;
512     auto zone = std::unique_ptr<TimeZone>(TimeZone::createTimeZone(timezoneStr.c_str()));
513     calendar->setTimeZone(*zone);
514     dateFormat->setTimeZone(*zone);
515     calendar->setTime((UDate)milliseconds, status);
516     dateFormat->format(calendar->getTime(status), dateString, status);
517     dateString.toUTF8String(result);
518     return result;
519 }
520 
FormatRange(int64_t fromMilliseconds,int64_t toMilliseconds)521 std::string DateTimeFormat::FormatRange(int64_t fromMilliseconds, int64_t toMilliseconds)
522 {
523     if (!createSuccess) {
524         return "";
525     }
526     UErrorCode status = U_ZERO_ERROR;
527     std::string result;
528     UnicodeString dateString;
529     calendar->clear();
530     std::string timezoneStr = timeZone.empty() ? GetSystemTimezone() : timeZone;
531     auto zone = std::unique_ptr<TimeZone>(TimeZone::createTimeZone(timezoneStr.c_str()));
532     calendar->setTimeZone(*zone);
533     dateIntvFormat->setTimeZone(*zone);
534     calendar->setTime((UDate)fromMilliseconds, status);
535 
536     auto toCalendar = std::unique_ptr<Calendar>(Calendar::createInstance(locale, status));
537     if (status != U_ZERO_ERROR || toCalendar == nullptr) {
538         return "";
539     }
540     toCalendar->clear();
541     toCalendar->setTimeZone(*zone);
542     toCalendar->setTime((UDate)toMilliseconds, status);
543     FieldPosition pos = 0;
544     dateIntvFormat->format(*calendar, *toCalendar, dateString, pos, status);
545     dateString.toUTF8String(result);
546     return result;
547 }
548 
GetResolvedOptions(std::map<std::string,std::string> & map)549 void DateTimeFormat::GetResolvedOptions(std::map<std::string, std::string> &map)
550 {
551     map.insert(std::make_pair("locale", localeTag));
552     if (!(localeInfo->GetCalendar()).empty()) {
553         map.insert(std::make_pair("calendar", localeInfo->GetCalendar()));
554     } else {
555         map.insert(std::make_pair("calendar", calendar->getType()));
556     }
557     if (!dateStyle.empty()) {
558         map.insert(std::make_pair("dateStyle", dateStyle));
559     }
560     if (!timeStyle.empty()) {
561         map.insert(std::make_pair("timeStyle", timeStyle));
562     }
563     if (!hourCycle.empty()) {
564         map.insert(std::make_pair("hourCycle", hourCycle));
565     } else if (!(localeInfo->GetHourCycle()).empty()) {
566         map.insert(std::make_pair("hourCycle", localeInfo->GetHourCycle()));
567     }
568     if (!timeZone.empty()) {
569         map.insert(std::make_pair("timeZone", timeZone));
570     } else {
571         UnicodeString timeZoneID("");
572         std::string timeZoneString;
573         dateFormat->getTimeZone().getID(timeZoneID).toUTF8String(timeZoneString);
574         map.insert(std::make_pair("timeZone", timeZoneString));
575     }
576     if (!timeZoneName.empty()) {
577         map.insert(std::make_pair("timeZoneName", timeZoneName));
578     }
579     if (!numberingSystem.empty()) {
580         map.insert(std::make_pair("numberingSystem", numberingSystem));
581     } else if (!(localeInfo->GetNumberingSystem()).empty()) {
582         map.insert(std::make_pair("numberingSystem", localeInfo->GetNumberingSystem()));
583     } else {
584         UErrorCode status = U_ZERO_ERROR;
585         auto numSys = std::unique_ptr<NumberingSystem>(NumberingSystem::createInstance(locale, status));
586         if (status != U_ZERO_ERROR) {
587             map.insert(std::make_pair("numberingSystem", numSys->getName()));
588         }
589     }
590     GetAdditionalResolvedOptions(map);
591 }
592 
GetAdditionalResolvedOptions(std::map<std::string,std::string> & map)593 void DateTimeFormat::GetAdditionalResolvedOptions(std::map<std::string, std::string> &map)
594 {
595     if (!hour12.empty()) {
596         map.insert(std::make_pair("hour12", hour12));
597     }
598     if (!weekday.empty()) {
599         map.insert(std::make_pair("weekday", weekday));
600     }
601     if (!era.empty()) {
602         map.insert(std::make_pair("era", era));
603     }
604     if (!year.empty()) {
605         map.insert(std::make_pair("year", year));
606     }
607     if (!month.empty()) {
608         map.insert(std::make_pair("month", month));
609     }
610     if (!day.empty()) {
611         map.insert(std::make_pair("day", day));
612     }
613     if (!hour.empty()) {
614         map.insert(std::make_pair("hour", hour));
615     }
616     if (!minute.empty()) {
617         map.insert(std::make_pair("minute", minute));
618     }
619     if (!second.empty()) {
620         map.insert(std::make_pair("second", second));
621     }
622     if (!dayPeriod.empty()) {
623         map.insert(std::make_pair("dayPeriod", dayPeriod));
624     }
625     if (!localeMatcher.empty()) {
626         map.insert(std::make_pair("localeMatcher", localeMatcher));
627     }
628     if (!formatMatcher.empty()) {
629         map.insert(std::make_pair("formatMatcher", formatMatcher));
630     }
631 }
632 
GetDateStyle() const633 std::string DateTimeFormat::GetDateStyle() const
634 {
635     return dateStyle;
636 }
637 
GetTimeStyle() const638 std::string DateTimeFormat::GetTimeStyle() const
639 {
640     return timeStyle;
641 }
642 
GetHourCycle() const643 std::string DateTimeFormat::GetHourCycle() const
644 {
645     return hourCycle;
646 }
647 
GetTimeZone() const648 std::string DateTimeFormat::GetTimeZone() const
649 {
650     return timeZone;
651 }
652 
GetTimeZoneName() const653 std::string DateTimeFormat::GetTimeZoneName() const
654 {
655     return timeZoneName;
656 }
657 
GetNumberingSystem() const658 std::string DateTimeFormat::GetNumberingSystem() const
659 {
660     return numberingSystem;
661 }
662 
GetHour12() const663 std::string DateTimeFormat::GetHour12() const
664 {
665     return hour12;
666 }
667 
GetWeekday() const668 std::string DateTimeFormat::GetWeekday() const
669 {
670     return weekday;
671 }
672 
GetEra() const673 std::string DateTimeFormat::GetEra() const
674 {
675     return era;
676 }
677 
GetYear() const678 std::string DateTimeFormat::GetYear() const
679 {
680     return year;
681 }
682 
GetMonth() const683 std::string DateTimeFormat::GetMonth() const
684 {
685     return month;
686 }
687 
GetDay() const688 std::string DateTimeFormat::GetDay() const
689 {
690     return day;
691 }
692 
GetHour() const693 std::string DateTimeFormat::GetHour() const
694 {
695     return hour;
696 }
697 
GetMinute() const698 std::string DateTimeFormat::GetMinute() const
699 {
700     return minute;
701 }
702 
GetSecond() const703 std::string DateTimeFormat::GetSecond() const
704 {
705     return second;
706 }
707 
Init()708 bool DateTimeFormat::Init()
709 {
710     SetHwIcuDirectory();
711     return true;
712 }
713 } // namespace I18n
714 } // namespace Global
715 } // namespace OHOS
716