• 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 
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