• 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         pattern.append("yMd");
370     }
371     AddOptions(year, yearChar);
372     AddOptions(month, monthChar);
373     AddOptions(day, dayChar);
374     AddOptions(hour, hourChar);
375     AddOptions(minute, minuteChar);
376     AddOptions(second, secondChar);
377     if ((hourCycle == "h12" || hourCycle == "h11" || hour12 == "true") && !hour.empty()) {
378         pattern.append(amPmChar);
379     }
380     AddOptions(timeZoneName, timeZoneChar);
381     AddOptions(weekday, weekdayChar);
382     AddOptions(era, eraChar);
383 }
384 
AddOptions(std::string option,char16_t optionChar)385 void DateTimeFormat::AddOptions(std::string option, char16_t optionChar)
386 {
387     if (!option.empty()) {
388         pattern.append(optionChar);
389     }
390 }
391 
ComputeHourCycleChars()392 void DateTimeFormat::ComputeHourCycleChars()
393 {
394     if (!hour12.empty()) {
395         if (hour12 == "true") {
396             hourNumericString = "h";
397             hourTwoDigitString = "hh";
398         } else {
399             hourNumericString = "H";
400             hourTwoDigitString = "HH";
401         }
402     } else {
403         if (hourCycle == "h11") {
404             hourNumericString = "K";
405             hourTwoDigitString = "KK";
406         } else if (hourCycle == "h12") {
407             hourNumericString = "h";
408             hourTwoDigitString = "hh";
409         } else if (hourCycle == "h23") {
410             hourNumericString = "H";
411             hourTwoDigitString = "HH";
412         } else if (hourCycle == "h24") {
413             hourNumericString = "k";
414             hourTwoDigitString = "kk";
415         }
416     }
417 }
418 
ComputePattern()419 void DateTimeFormat::ComputePattern()
420 {
421     ComputePartOfPattern(year, yearChar, "yy", "Y");
422     ComputePartOfPattern(day, dayChar, "dd", "d");
423     ComputePartOfPattern(hour, hourChar, hourTwoDigitString, hourNumericString);
424     ComputePartOfPattern(minute, minuteChar, "mm", "mm");
425     ComputePartOfPattern(second, secondChar, "ss", "ss");
426     if (!month.empty()) {
427         UnicodeString monthOfPattern = UnicodeString(monthChar);
428         int32_t length = monthOfPattern.length();
429         if (month == "numeric" && length != NUMERIC_LENGTH) {
430             pattern.findAndReplace(monthOfPattern, UnicodeString::fromUTF8(StringPiece("M")));
431         } else if (month == "2-digit" && length != TWO_DIGIT_LENGTH) {
432             pattern.findAndReplace(monthOfPattern, UnicodeString::fromUTF8(StringPiece("MM")));
433         } else if (month == "long" && length != LONG_LENGTH) {
434             pattern.findAndReplace(monthOfPattern, UnicodeString::fromUTF8(StringPiece("MMMM")));
435         } else if (month == "short" && length != SHORT_LENGTH) {
436             pattern.findAndReplace(monthOfPattern, UnicodeString::fromUTF8(StringPiece("MMM")));
437         } else if (month == "narrow" && length != NARROW_LENGTH) {
438             pattern.findAndReplace(monthOfPattern, UnicodeString::fromUTF8(StringPiece("MMMMM")));
439         }
440     }
441     if (!timeZoneName.empty()) {
442         UnicodeString timeZoneOfPattern = UnicodeString(timeZoneChar);
443         if (timeZoneName == "long") {
444             pattern.findAndReplace(timeZoneOfPattern, UnicodeString::fromUTF8(StringPiece("zzzz")));
445         } else if (timeZoneName == "short") {
446             pattern.findAndReplace(timeZoneOfPattern, UnicodeString::fromUTF8(StringPiece("O")));
447         }
448     }
449 
450     ComputeWeekdayOrEraOfPattern(weekday, weekdayChar, "EEEE", "E", "EEEEE");
451     ComputeWeekdayOrEraOfPattern(era, eraChar, "GGGG", "G", "GGGGG");
452 }
453 
ComputePartOfPattern(std::string option,char16_t character,std::string twoDigitChar,std::string numericChar)454 void DateTimeFormat::ComputePartOfPattern(std::string option, char16_t character, std::string twoDigitChar,
455     std::string numericChar)
456 {
457     if (!option.empty()) {
458         UnicodeString curPartOfPattern = UnicodeString(character);
459         if (option == "2-digit") {
460             pattern.findAndReplace(curPartOfPattern, UnicodeString::fromUTF8(StringPiece(twoDigitChar)));
461         } else if (option == "numeric") {
462             pattern.findAndReplace(curPartOfPattern, UnicodeString::fromUTF8(StringPiece(numericChar)));
463         }
464     }
465 }
466 
ComputeWeekdayOrEraOfPattern(std::string option,char16_t character,std::string longChar,std::string shortChar,std::string narrowChar)467 void DateTimeFormat::ComputeWeekdayOrEraOfPattern(std::string option, char16_t character, std::string longChar,
468     std::string shortChar, std::string narrowChar)
469 {
470     if (!option.empty()) {
471         UnicodeString curPartOfPattern = UnicodeString(character);
472         int32_t length = curPartOfPattern.length();
473         if (option == "long" && length != LONG_ERA_LENGTH) {
474             pattern.findAndReplace(curPartOfPattern, UnicodeString::fromUTF8(StringPiece(longChar)));
475         } else if (option == "short" && length != SHORT_ERA_LENGTH) {
476             pattern.findAndReplace(curPartOfPattern, UnicodeString::fromUTF8(StringPiece(shortChar)));
477         } else if (option == "narrow" && length != NARROW_LENGTH) {
478             pattern.findAndReplace(curPartOfPattern, UnicodeString::fromUTF8(StringPiece(narrowChar)));
479         }
480     }
481 }
482 
GetArrayValue(int64_t * dateArray,size_t index,size_t size)483 int64_t DateTimeFormat::GetArrayValue(int64_t *dateArray, size_t index, size_t size)
484 {
485     if (index < size) {
486         return dateArray[index];
487     } else {
488         return 0;
489     }
490 }
491 
GetSystemTimezone()492 std::string DateTimeFormat::GetSystemTimezone()
493 {
494     std::string systemTimezone = ReadSystemParameter(TIMEZONE_KEY, SYS_PARAM_LEN);
495     if (systemTimezone.length() == 0) {
496         systemTimezone = DEFAULT_TIMEZONE;
497     }
498     return systemTimezone;
499 }
500 
Format(int64_t milliseconds)501 std::string DateTimeFormat::Format(int64_t milliseconds)
502 {
503     if (!createSuccess) {
504         return "";
505     }
506     UErrorCode status = U_ZERO_ERROR;
507     std::string result;
508     UnicodeString dateString;
509     calendar->clear();
510     std::string timezoneStr = timeZone.empty() ? GetSystemTimezone() : timeZone;
511     auto zone = std::unique_ptr<TimeZone>(TimeZone::createTimeZone(timezoneStr.c_str()));
512     calendar->setTimeZone(*zone);
513     dateFormat->setTimeZone(*zone);
514     calendar->setTime((UDate)milliseconds, status);
515     dateFormat->format(calendar->getTime(status), dateString, status);
516     dateString.toUTF8String(result);
517     return result;
518 }
519 
FormatRange(int64_t fromMilliseconds,int64_t toMilliseconds)520 std::string DateTimeFormat::FormatRange(int64_t fromMilliseconds, int64_t toMilliseconds)
521 {
522     if (!createSuccess) {
523         return "";
524     }
525     UErrorCode status = U_ZERO_ERROR;
526     std::string result;
527     UnicodeString dateString;
528     calendar->clear();
529     std::string timezoneStr = timeZone.empty() ? GetSystemTimezone() : timeZone;
530     auto zone = std::unique_ptr<TimeZone>(TimeZone::createTimeZone(timezoneStr.c_str()));
531     calendar->setTimeZone(*zone);
532     dateIntvFormat->setTimeZone(*zone);
533     calendar->setTime((UDate)fromMilliseconds, status);
534 
535     auto toCalendar = std::unique_ptr<Calendar>(Calendar::createInstance(locale, status));
536     if (status != U_ZERO_ERROR || toCalendar == nullptr) {
537         return "";
538     }
539     toCalendar->clear();
540     toCalendar->setTimeZone(*zone);
541     toCalendar->setTime((UDate)toMilliseconds, status);
542     FieldPosition pos = 0;
543     dateIntvFormat->format(*calendar, *toCalendar, dateString, pos, status);
544     dateString.toUTF8String(result);
545     return result;
546 }
547 
GetResolvedOptions(std::map<std::string,std::string> & map)548 void DateTimeFormat::GetResolvedOptions(std::map<std::string, std::string> &map)
549 {
550     map.insert(std::make_pair("locale", localeTag));
551     if (!(localeInfo->GetCalendar()).empty()) {
552         map.insert(std::make_pair("calendar", localeInfo->GetCalendar()));
553     } else {
554         map.insert(std::make_pair("calendar", calendar->getType()));
555     }
556     if (!dateStyle.empty()) {
557         map.insert(std::make_pair("dateStyle", dateStyle));
558     }
559     if (!timeStyle.empty()) {
560         map.insert(std::make_pair("timeStyle", timeStyle));
561     }
562     if (!hourCycle.empty()) {
563         map.insert(std::make_pair("hourCycle", hourCycle));
564     } else if (!(localeInfo->GetHourCycle()).empty()) {
565         map.insert(std::make_pair("hourCycle", localeInfo->GetHourCycle()));
566     }
567     if (!timeZone.empty()) {
568         map.insert(std::make_pair("timeZone", timeZone));
569     } else {
570         UnicodeString timeZoneID("");
571         std::string timeZoneString;
572         dateFormat->getTimeZone().getID(timeZoneID).toUTF8String(timeZoneString);
573         map.insert(std::make_pair("timeZone", timeZoneString));
574     }
575     if (!timeZoneName.empty()) {
576         map.insert(std::make_pair("timeZoneName", timeZoneName));
577     }
578     if (!numberingSystem.empty()) {
579         map.insert(std::make_pair("numberingSystem", numberingSystem));
580     } else if (!(localeInfo->GetNumberingSystem()).empty()) {
581         map.insert(std::make_pair("numberingSystem", localeInfo->GetNumberingSystem()));
582     } else {
583         UErrorCode status = U_ZERO_ERROR;
584         auto numSys = std::unique_ptr<NumberingSystem>(NumberingSystem::createInstance(locale, status));
585         if (status != U_ZERO_ERROR) {
586             map.insert(std::make_pair("numberingSystem", numSys->getName()));
587         }
588     }
589     GetAdditionalResolvedOptions(map);
590 }
591 
GetAdditionalResolvedOptions(std::map<std::string,std::string> & map)592 void DateTimeFormat::GetAdditionalResolvedOptions(std::map<std::string, std::string> &map)
593 {
594     if (!hour12.empty()) {
595         map.insert(std::make_pair("hour12", hour12));
596     }
597     if (!weekday.empty()) {
598         map.insert(std::make_pair("weekday", weekday));
599     }
600     if (!era.empty()) {
601         map.insert(std::make_pair("era", era));
602     }
603     if (!year.empty()) {
604         map.insert(std::make_pair("year", year));
605     }
606     if (!month.empty()) {
607         map.insert(std::make_pair("month", month));
608     }
609     if (!day.empty()) {
610         map.insert(std::make_pair("day", day));
611     }
612     if (!hour.empty()) {
613         map.insert(std::make_pair("hour", hour));
614     }
615     if (!minute.empty()) {
616         map.insert(std::make_pair("minute", minute));
617     }
618     if (!second.empty()) {
619         map.insert(std::make_pair("second", second));
620     }
621     if (!dayPeriod.empty()) {
622         map.insert(std::make_pair("dayPeriod", dayPeriod));
623     }
624     if (!localeMatcher.empty()) {
625         map.insert(std::make_pair("localeMatcher", localeMatcher));
626     }
627     if (!formatMatcher.empty()) {
628         map.insert(std::make_pair("formatMatcher", formatMatcher));
629     }
630 }
631 
GetDateStyle() const632 std::string DateTimeFormat::GetDateStyle() const
633 {
634     return dateStyle;
635 }
636 
GetTimeStyle() const637 std::string DateTimeFormat::GetTimeStyle() const
638 {
639     return timeStyle;
640 }
641 
GetHourCycle() const642 std::string DateTimeFormat::GetHourCycle() const
643 {
644     return hourCycle;
645 }
646 
GetTimeZone() const647 std::string DateTimeFormat::GetTimeZone() const
648 {
649     return timeZone;
650 }
651 
GetTimeZoneName() const652 std::string DateTimeFormat::GetTimeZoneName() const
653 {
654     return timeZoneName;
655 }
656 
GetNumberingSystem() const657 std::string DateTimeFormat::GetNumberingSystem() const
658 {
659     return numberingSystem;
660 }
661 
GetHour12() const662 std::string DateTimeFormat::GetHour12() const
663 {
664     return hour12;
665 }
666 
GetWeekday() const667 std::string DateTimeFormat::GetWeekday() const
668 {
669     return weekday;
670 }
671 
GetEra() const672 std::string DateTimeFormat::GetEra() const
673 {
674     return era;
675 }
676 
GetYear() const677 std::string DateTimeFormat::GetYear() const
678 {
679     return year;
680 }
681 
GetMonth() const682 std::string DateTimeFormat::GetMonth() const
683 {
684     return month;
685 }
686 
GetDay() const687 std::string DateTimeFormat::GetDay() const
688 {
689     return day;
690 }
691 
GetHour() const692 std::string DateTimeFormat::GetHour() const
693 {
694     return hour;
695 }
696 
GetMinute() const697 std::string DateTimeFormat::GetMinute() const
698 {
699     return minute;
700 }
701 
GetSecond() const702 std::string DateTimeFormat::GetSecond() const
703 {
704     return second;
705 }
706 
Init()707 bool DateTimeFormat::Init()
708 {
709     SetHwIcuDirectory();
710     return true;
711 }
712 } // namespace I18n
713 } // namespace Global
714 } // namespace OHOS
715