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_sequence.h"
16 #include "i18n_hilog.h"
17 #include "unicode/datefmt.h"
18 #include "unicode/locid.h"
19 #include "unicode/smpdtfmt.h"
20 #include "unicode/dtptngen.h"
21 #include <regex>
22
23 namespace OHOS {
24 namespace Global {
25 namespace I18n {
26
27 const std::unordered_map<std::string, std::string> DateTimeSequence::DATE_ORDER_MAP = {
28 { "ug", "L-d-y" },
29 { "ar", "y-L-d" },
30 { "fa", "y-L-d" },
31 { "ur", "y-L-d" },
32 { "iw", "y-L-d" },
33 { "he", "y-L-d" },
34 };
35
GetDateOrder(const std::string & locale)36 std::string DateTimeSequence::GetDateOrder(const std::string &locale)
37 {
38 UErrorCode icuStatus = U_ZERO_ERROR;
39 icu::Locale localeObj = icu::Locale::forLanguageTag(locale.data(), icuStatus);
40 if (U_FAILURE(icuStatus)) {
41 HILOG_ERROR_I18N("Failed to create locale for GetDateOrder");
42 return "";
43 }
44 const char* language = localeObj.getBaseName();
45 if (language == nullptr) {
46 HILOG_ERROR_I18N("%{public}s getBaseName is null.", locale.c_str());
47 return "";
48 }
49 std::string languageTag = language;
50 if (DATE_ORDER_MAP.find(languageTag) != DATE_ORDER_MAP.end()) {
51 std::string dateOrder = DATE_ORDER_MAP.find(languageTag)->second;
52 return dateOrder;
53 }
54 icu::SimpleDateFormat* formatter = dynamic_cast<icu::SimpleDateFormat*>
55 (icu::DateFormat::createDateInstance(icu::DateFormat::EStyle::kDefault, localeObj));
56 if (U_FAILURE(icuStatus) || formatter == nullptr) {
57 HILOG_ERROR_I18N("Failed to create SimpleDateFormat");
58 return "";
59 }
60 std::string tempValue;
61 icu::UnicodeString unistr;
62 formatter->toPattern(unistr);
63 unistr.toUTF8String<std::string>(tempValue);
64 std::string value = ModifyOrder(tempValue);
65 delete formatter;
66 return value;
67 }
68
ModifyOrder(std::string & pattern)69 std::string DateTimeSequence::ModifyOrder(std::string &pattern)
70 {
71 int order[3] = { 0 }; // total 3 elements 'y', 'M'/'L', 'd'
72 int lengths[4] = { 0 }; // first elements is the currently found elememnts, thus 4 elements totally.
73 bool flag = true;
74 for (size_t i = 0; i < pattern.length(); ++i) {
75 char ch = pattern[i];
76 if (flag && std::isalpha(ch)) {
77 ProcessNormal(ch, order, 3, lengths, 4); // 3, 4 are lengths of these arrays
78 } else if (ch == '\'') {
79 flag = !flag;
80 }
81 }
82 std::unordered_map<char, int> pattern2index = {
83 { 'y', 1 },
84 { 'L', 2 },
85 { 'd', 3 },
86 };
87 std::string ret;
88 for (int i = 0; i < 3; ++i) { // 3 is the size of orders
89 auto it = pattern2index.find(order[i]);
90 if (it == pattern2index.end()) {
91 continue;
92 }
93 int index = it->second;
94 if ((lengths[index] > 0) && (lengths[index] <= 6)) { // 6 is the max length of a filed
95 ret.append(lengths[index], order[i]);
96 }
97 if (i < 2) { // 2 is the size of the order minus one
98 ret.append(1, '-');
99 }
100 }
101 return ret;
102 }
103
ProcessNormal(char ch,int * order,size_t orderSize,int * lengths,size_t lengsSize)104 void DateTimeSequence::ProcessNormal(char ch, int *order, size_t orderSize, int *lengths, size_t lengsSize)
105 {
106 char adjust;
107 int index = -1;
108 if (ch == 'd') {
109 adjust = 'd';
110 index = 3; // 3 is the index of 'd'
111 } else if ((ch == 'L') || (ch == 'M')) {
112 adjust = 'L';
113 index = 2; // 2 is the index of 'M'
114 } else if (ch == 'y') {
115 adjust = 'y';
116 index = 1;
117 } else {
118 return;
119 }
120 if ((index < 0) || (index >= static_cast<int>(lengsSize))) {
121 return;
122 }
123 if (lengths[index] == 0) {
124 if (lengths[0] >= 3) { // 3 is the index of order
125 return;
126 }
127 order[lengths[0]] = static_cast<int>(adjust);
128 ++lengths[0];
129 lengths[index] = 1;
130 } else {
131 ++lengths[index];
132 }
133 }
134
135 } // namespace I18n
136 } // namespace Global
137 } // namespace OHOS