• 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 (dateArray == nullptr) {
487         return 0;
488     }
489     if (index < size) {
490         return dateArray[index];
491     } else {
492         return 0;
493     }
494 }
495 
GetSystemTimezone()496 std::string DateTimeFormat::GetSystemTimezone()
497 {
498     std::string systemTimezone = ReadSystemParameter(TIMEZONE_KEY, SYS_PARAM_LEN);
499     if (systemTimezone.length() == 0) {
500         systemTimezone = DEFAULT_TIMEZONE;
501     }
502     return systemTimezone;
503 }
504 
Format(int64_t milliseconds)505 std::string DateTimeFormat::Format(int64_t milliseconds)
506 {
507     if (!createSuccess) {
508         return "";
509     }
510     UErrorCode status = U_ZERO_ERROR;
511     std::string result;
512     UnicodeString dateString;
513     calendar->clear();
514     std::string timezoneStr = timeZone.empty() ? GetSystemTimezone() : timeZone;
515     auto zone = std::unique_ptr<TimeZone>(TimeZone::createTimeZone(timezoneStr.c_str()));
516     if (zone != nullptr) {
517         calendar->setTimeZone(*zone);
518         dateFormat->setTimeZone(*zone);
519     }
520     calendar->setTime((UDate)milliseconds, status);
521     dateFormat->format(calendar->getTime(status), dateString, status);
522     dateString.toUTF8String(result);
523     return result;
524 }
525 
FormatRange(int64_t fromMilliseconds,int64_t toMilliseconds)526 std::string DateTimeFormat::FormatRange(int64_t fromMilliseconds, int64_t toMilliseconds)
527 {
528     if (!createSuccess || calendar == nullptr) {
529         return "";
530     }
531     UErrorCode status = U_ZERO_ERROR;
532     std::string result;
533     UnicodeString dateString;
534     calendar->clear();
535     std::string timezoneStr = timeZone.empty() ? GetSystemTimezone() : timeZone;
536     auto zone = std::unique_ptr<TimeZone>(TimeZone::createTimeZone(timezoneStr.c_str()));
537     if (zone != nullptr) {
538         calendar->setTimeZone(*zone);
539         dateIntvFormat->setTimeZone(*zone);
540     }
541     calendar->setTime((UDate)fromMilliseconds, status);
542 
543     auto toCalendar = std::unique_ptr<Calendar>(Calendar::createInstance(locale, status));
544     if (status != U_ZERO_ERROR || toCalendar == nullptr) {
545         return "";
546     }
547     toCalendar->clear();
548     if (zone != nullptr) {
549         toCalendar->setTimeZone(*zone);
550     }
551     toCalendar->setTime((UDate)toMilliseconds, status);
552     FieldPosition pos = 0;
553     dateIntvFormat->format(*calendar, *toCalendar, dateString, pos, status);
554     dateString.toUTF8String(result);
555     return result;
556 }
557 
GetResolvedOptions(std::map<std::string,std::string> & map)558 void DateTimeFormat::GetResolvedOptions(std::map<std::string, std::string> &map)
559 {
560     map.insert(std::make_pair("locale", localeTag));
561     if (!(localeInfo->GetCalendar()).empty()) {
562         map.insert(std::make_pair("calendar", localeInfo->GetCalendar()));
563     } else {
564         map.insert(std::make_pair("calendar", calendar->getType()));
565     }
566     if (!dateStyle.empty()) {
567         map.insert(std::make_pair("dateStyle", dateStyle));
568     }
569     if (!timeStyle.empty()) {
570         map.insert(std::make_pair("timeStyle", timeStyle));
571     }
572     if (!hourCycle.empty()) {
573         map.insert(std::make_pair("hourCycle", hourCycle));
574     } else if (!(localeInfo->GetHourCycle()).empty()) {
575         map.insert(std::make_pair("hourCycle", localeInfo->GetHourCycle()));
576     }
577     if (!timeZone.empty()) {
578         map.insert(std::make_pair("timeZone", timeZone));
579     } else {
580         UnicodeString timeZoneID("");
581         std::string timeZoneString;
582         dateFormat->getTimeZone().getID(timeZoneID).toUTF8String(timeZoneString);
583         map.insert(std::make_pair("timeZone", timeZoneString));
584     }
585     if (!timeZoneName.empty()) {
586         map.insert(std::make_pair("timeZoneName", timeZoneName));
587     }
588     if (!numberingSystem.empty()) {
589         map.insert(std::make_pair("numberingSystem", numberingSystem));
590     } else if (!(localeInfo->GetNumberingSystem()).empty()) {
591         map.insert(std::make_pair("numberingSystem", localeInfo->GetNumberingSystem()));
592     } else {
593         UErrorCode status = U_ZERO_ERROR;
594         auto numSys = std::unique_ptr<NumberingSystem>(NumberingSystem::createInstance(locale, status));
595         if (status != U_ZERO_ERROR) {
596             map.insert(std::make_pair("numberingSystem", numSys->getName()));
597         }
598     }
599     GetAdditionalResolvedOptions(map);
600 }
601 
GetAdditionalResolvedOptions(std::map<std::string,std::string> & map)602 void DateTimeFormat::GetAdditionalResolvedOptions(std::map<std::string, std::string> &map)
603 {
604     if (!hour12.empty()) {
605         map.insert(std::make_pair("hour12", hour12));
606     }
607     if (!weekday.empty()) {
608         map.insert(std::make_pair("weekday", weekday));
609     }
610     if (!era.empty()) {
611         map.insert(std::make_pair("era", era));
612     }
613     if (!year.empty()) {
614         map.insert(std::make_pair("year", year));
615     }
616     if (!month.empty()) {
617         map.insert(std::make_pair("month", month));
618     }
619     if (!day.empty()) {
620         map.insert(std::make_pair("day", day));
621     }
622     if (!hour.empty()) {
623         map.insert(std::make_pair("hour", hour));
624     }
625     if (!minute.empty()) {
626         map.insert(std::make_pair("minute", minute));
627     }
628     if (!second.empty()) {
629         map.insert(std::make_pair("second", second));
630     }
631     if (!dayPeriod.empty()) {
632         map.insert(std::make_pair("dayPeriod", dayPeriod));
633     }
634     if (!localeMatcher.empty()) {
635         map.insert(std::make_pair("localeMatcher", localeMatcher));
636     }
637     if (!formatMatcher.empty()) {
638         map.insert(std::make_pair("formatMatcher", formatMatcher));
639     }
640 }
641 
GetDateStyle() const642 std::string DateTimeFormat::GetDateStyle() const
643 {
644     return dateStyle;
645 }
646 
GetTimeStyle() const647 std::string DateTimeFormat::GetTimeStyle() const
648 {
649     return timeStyle;
650 }
651 
GetHourCycle() const652 std::string DateTimeFormat::GetHourCycle() const
653 {
654     return hourCycle;
655 }
656 
GetTimeZone() const657 std::string DateTimeFormat::GetTimeZone() const
658 {
659     return timeZone;
660 }
661 
GetTimeZoneName() const662 std::string DateTimeFormat::GetTimeZoneName() const
663 {
664     return timeZoneName;
665 }
666 
GetNumberingSystem() const667 std::string DateTimeFormat::GetNumberingSystem() const
668 {
669     return numberingSystem;
670 }
671 
GetHour12() const672 std::string DateTimeFormat::GetHour12() const
673 {
674     return hour12;
675 }
676 
GetWeekday() const677 std::string DateTimeFormat::GetWeekday() const
678 {
679     return weekday;
680 }
681 
GetEra() const682 std::string DateTimeFormat::GetEra() const
683 {
684     return era;
685 }
686 
GetYear() const687 std::string DateTimeFormat::GetYear() const
688 {
689     return year;
690 }
691 
GetMonth() const692 std::string DateTimeFormat::GetMonth() const
693 {
694     return month;
695 }
696 
GetDay() const697 std::string DateTimeFormat::GetDay() const
698 {
699     return day;
700 }
701 
GetHour() const702 std::string DateTimeFormat::GetHour() const
703 {
704     return hour;
705 }
706 
GetMinute() const707 std::string DateTimeFormat::GetMinute() const
708 {
709     return minute;
710 }
711 
GetSecond() const712 std::string DateTimeFormat::GetSecond() const
713 {
714     return second;
715 }
716 
Init()717 bool DateTimeFormat::Init()
718 {
719     SetHwIcuDirectory();
720     return true;
721 }
722 } // namespace I18n
723 } // namespace Global
724 } // namespace OHOS
725