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
16 #include "zone_util.h"
17 #include "ohos/init_data.h"
18 #include "strenum.h"
19 #include "unicode/timezone.h"
20
21 using namespace OHOS::Global::I18n;
22 using namespace icu;
23 using namespace std;
24
25
26 unordered_map<string, string> ZoneUtil::defaultMap = {
27 {"AQ", "Antarctica/McMurdo"},
28 {"AR", "America/Argentina/Buenos_Aires"},
29 {"AU", "Australia/Sydney"},
30 {"BR", "America/Noronha"},
31 {"CA", "America/St_Johns"},
32 {"CD", "Africa/Kinshasa"},
33 {"CL", "America/Santiago"},
34 {"CN", "Asia/Shanghai"},
35 {"CY", "Asia/Nicosia"},
36 {"DE", "Europe/Berlin"},
37 {"EC", "America/Guayaquil"},
38 {"ES", "Europe/Madrid"},
39 {"FM", "Pacific/Pohnpei"},
40 {"GL", "America/Godthab"},
41 {"ID", "Asia/Jakarta"},
42 {"KI", "Pacific/Tarawa"},
43 {"KZ", "Asia/Almaty"},
44 {"MH", "Pacific/Majuro"},
45 {"MN", "Asia/Ulaanbaatar"},
46 {"MX", "America/Mexico_City"},
47 {"MY", "Asia/Kuala_Lumpur"},
48 {"NZ", "Pacific/Auckland"},
49 {"PF", "Pacific/Tahiti"},
50 {"PG", "Pacific/Port_Moresby"},
51 {"PS", "Asia/Gaza"},
52 {"PT", "Europe/Lisbon"},
53 {"RU", "Europe/Moscow"},
54 {"UA", "Europe/Kiev"},
55 {"UM", "Pacific/Wake"},
56 {"US", "America/New_York"},
57 {"UZ", "Asia/Tashkent"},
58 };
59
60 bool ZoneUtil::icuInitialized = ZoneUtil::Init();
61
GetDefaultZone(const string & country)62 string ZoneUtil::GetDefaultZone(const string &country)
63 {
64 string temp(country);
65 for (size_t i = 0; i < temp.size(); i++) {
66 temp[i] = (char)toupper(temp[i]);
67 }
68 if (defaultMap.find(temp) != defaultMap.end()) {
69 return defaultMap[temp];
70 }
71 string ret;
72 StringEnumeration *strEnum = TimeZone::createEnumeration(temp.c_str());
73 GetString(strEnum, ret);
74 if (strEnum != nullptr) {
75 delete strEnum;
76 }
77 return ret;
78 }
79
GetDefaultZone(const int32_t number)80 string ZoneUtil::GetDefaultZone(const int32_t number)
81 {
82 string *region_code = new(nothrow) string();
83 if (!region_code) {
84 return "";
85 }
86 phone_util.GetRegionCodeForCountryCode(number, region_code);
87 if (!region_code) {
88 return "";
89 }
90 string ret = GetDefaultZone(*region_code);
91 delete region_code;
92 return ret;
93 }
94
GetDefaultZone(const string country,const int32_t offset)95 string ZoneUtil::GetDefaultZone(const string country, const int32_t offset)
96 {
97 UErrorCode status = U_ZERO_ERROR;
98 StringEnumeration *strEnum =
99 TimeZone::createTimeZoneIDEnumeration(UCAL_ZONE_TYPE_ANY, country.c_str(), &offset, status);
100 if (status != U_ZERO_ERROR) {
101 return "";
102 }
103 string ret;
104 GetString(strEnum, ret);
105 if (strEnum != nullptr) {
106 delete strEnum;
107 strEnum = nullptr;
108 }
109 return ret;
110 }
111
GetDefaultZone(const int32_t number,const int32_t offset)112 string ZoneUtil::GetDefaultZone(const int32_t number, const int32_t offset)
113 {
114 string *region_code = new(nothrow) string();
115 if (!region_code) {
116 return "";
117 }
118 phone_util.GetRegionCodeForCountryCode(number, region_code);
119 if (!region_code) {
120 return "";
121 }
122 string ret = GetDefaultZone(*region_code, offset);
123 delete region_code;
124 return ret;
125 }
126
GetZoneList(const string country,vector<string> & retVec)127 void ZoneUtil::GetZoneList(const string country, vector<string> &retVec)
128 {
129 StringEnumeration *strEnum = TimeZone::createEnumeration(country.c_str());
130 GetList(strEnum, retVec);
131 if (strEnum != nullptr) {
132 delete strEnum;
133 strEnum = nullptr;
134 }
135 }
136
GetZoneList(const string country,const int32_t offset,vector<string> & retVec)137 void ZoneUtil::GetZoneList(const string country, const int32_t offset, vector<string> &retVec)
138 {
139 UErrorCode status = U_ZERO_ERROR;
140 StringEnumeration *strEnum =
141 TimeZone::createTimeZoneIDEnumeration(UCAL_ZONE_TYPE_ANY, country.c_str(), &offset, status);
142 if (status != U_ZERO_ERROR) {
143 delete strEnum;
144 strEnum = nullptr;
145 return;
146 }
147 GetList(strEnum, retVec);
148 if (strEnum != nullptr) {
149 delete strEnum;
150 strEnum = nullptr;
151 }
152 }
153
GetString(StringEnumeration * strEnum,string & ret)154 void ZoneUtil::GetString(StringEnumeration *strEnum, string& ret)
155 {
156 UErrorCode status = U_ZERO_ERROR;
157 UnicodeString uniString;
158 if (!strEnum) {
159 return;
160 }
161 int32_t count = strEnum->count(status);
162 if ((status != U_ZERO_ERROR) || count <= 0) {
163 return;
164 }
165 const UnicodeString *uniStr = strEnum->snext(status);
166 if ((status != U_ZERO_ERROR) || (!uniStr)) {
167 return;
168 }
169 UnicodeString canonicalUnistring;
170 TimeZone::getCanonicalID(*uniStr, canonicalUnistring, status);
171 if (status != U_ZERO_ERROR) {
172 return;
173 }
174 canonicalUnistring.toUTF8String(ret);
175 return;
176 }
177
GetList(StringEnumeration * strEnum,vector<string> & retVec)178 void ZoneUtil::GetList(StringEnumeration *strEnum, vector<string> &retVec)
179 {
180 if (!strEnum) {
181 return;
182 }
183 UErrorCode status = U_ZERO_ERROR;
184 int32_t count = strEnum->count(status);
185 if (count <= 0 || status != U_ZERO_ERROR) {
186 return;
187 }
188 while (count > 0) {
189 const UnicodeString *uniStr = strEnum->snext(status);
190 if ((!uniStr) || (status != U_ZERO_ERROR)) {
191 retVec.clear();
192 break;
193 }
194 UnicodeString canonicalUnistring;
195 TimeZone::getCanonicalID(*uniStr, canonicalUnistring, status);
196 if (status != U_ZERO_ERROR) {
197 retVec.clear();
198 break;
199 }
200 string canonicalString = "";
201 canonicalUnistring.toUTF8String(canonicalString);
202 if ((canonicalString != "") && (find(retVec.begin(), retVec.end(), canonicalString) == retVec.end())) {
203 retVec.push_back(canonicalString);
204 }
205 --count;
206 }
207 return;
208 }
209
Init()210 bool ZoneUtil::Init()
211 {
212 SetHwIcuDirectory();
213 return true;
214 }
215