19596a2c1Sopenharmony_ci/*
29596a2c1Sopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
39596a2c1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
49596a2c1Sopenharmony_ci * you may not use this file except in compliance with the License.
59596a2c1Sopenharmony_ci * You may obtain a copy of the License at
69596a2c1Sopenharmony_ci *
79596a2c1Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
89596a2c1Sopenharmony_ci *
99596a2c1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
109596a2c1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
119596a2c1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129596a2c1Sopenharmony_ci * See the License for the specific language governing permissions and
139596a2c1Sopenharmony_ci * limitations under the License.
149596a2c1Sopenharmony_ci */
159596a2c1Sopenharmony_ci#include "i18n_timezone.h"
169596a2c1Sopenharmony_ci
179596a2c1Sopenharmony_ci#include <dlfcn.h>
189596a2c1Sopenharmony_ci#include <filesystem>
199596a2c1Sopenharmony_ci#include <fstream>
209596a2c1Sopenharmony_ci#include <sys/stat.h>
219596a2c1Sopenharmony_ci#include "i18n_hilog.h"
229596a2c1Sopenharmony_ci#include "libxml/globals.h"
239596a2c1Sopenharmony_ci#include "libxml/tree.h"
249596a2c1Sopenharmony_ci#include "libxml/xmlstring.h"
259596a2c1Sopenharmony_ci#include "locale_config.h"
269596a2c1Sopenharmony_ci#include "locale_matcher.h"
279596a2c1Sopenharmony_ci#include "locale_info.h"
289596a2c1Sopenharmony_ci#include "map"
299596a2c1Sopenharmony_ci#include "securec.h"
309596a2c1Sopenharmony_ci#include "set"
319596a2c1Sopenharmony_ci#include "string"
329596a2c1Sopenharmony_ci#include "type_traits"
339596a2c1Sopenharmony_ci#include "unicode/umachine.h"
349596a2c1Sopenharmony_ci#include "utility"
359596a2c1Sopenharmony_ci#include "utils.h"
369596a2c1Sopenharmony_ci#include "unicode/utypes.h"
379596a2c1Sopenharmony_ci#include "vector"
389596a2c1Sopenharmony_ci#include "unicode/locid.h"
399596a2c1Sopenharmony_ci#include "unicode/unistr.h"
409596a2c1Sopenharmony_ci#include "utils.h"
419596a2c1Sopenharmony_ci#include <cstdio>
429596a2c1Sopenharmony_ci#include <cstdlib>
439596a2c1Sopenharmony_ci#include <iostream>
449596a2c1Sopenharmony_ci#include <regex>
459596a2c1Sopenharmony_ci
469596a2c1Sopenharmony_cinamespace OHOS {
479596a2c1Sopenharmony_cinamespace Global {
489596a2c1Sopenharmony_cinamespace I18n {
499596a2c1Sopenharmony_ciusing namespace std::filesystem;
509596a2c1Sopenharmony_ci
519596a2c1Sopenharmony_ciconst char *I18nTimeZone::TIMEZONE_KEY = "persist.time.timezone";
529596a2c1Sopenharmony_ciconst char *I18nTimeZone::DEFAULT_TIMEZONE = "GMT";
539596a2c1Sopenharmony_ci
549596a2c1Sopenharmony_ciconst char *I18nTimeZone::CITY_TIMEZONE_DATA_PATH = "/system/usr/ohos_timezone/ohos_timezones.xml";
559596a2c1Sopenharmony_ciconst char *I18nTimeZone::DEVICE_CITY_TIMEZONE_DATA_PATH = "/system/usr/ohos_timezone/device_timezones.xml";
569596a2c1Sopenharmony_ciconst char *I18nTimeZone::DISTRO_DEVICE_CITY_TIMEZONE_DATA_PATH = "/system/etc/tzdata_distro/device_timezones.xml";
579596a2c1Sopenharmony_ciconst char *I18nTimeZone::TZ_PIXEL_PATH = "/system/usr/ohos_timezone";
589596a2c1Sopenharmony_ciconst char *I18nTimeZone::DISTRO_TZ_PIXEL_PATH = "/system/etc/tzdata_distro";
599596a2c1Sopenharmony_ciconst char *I18nTimeZone::DEFAULT_LOCALE = "root";
609596a2c1Sopenharmony_ciconst char *I18nTimeZone::CITY_DISPLAYNAME_PATH = "/system/usr/ohos_timezone/ohos_city_dispname/";
619596a2c1Sopenharmony_ciconst char *I18nTimeZone::BASE_DEVICE_CITY_DISPLAYNAME_PATH = "/system/usr/ohos_timezone/device_city_dispname/";
629596a2c1Sopenharmony_ciconst char *I18nTimeZone::DISTRO_DEVICE_CITY_DISPLAYNAME_PATH = "/system/etc/tzdata_distro/device_city_dispname/";
639596a2c1Sopenharmony_ciconst char *I18nTimeZone::DISTRO_ROOT_DISPLAYNAME_PATH = "/system/etc/tzdata_distro/device_city_dispname/root.xml";
649596a2c1Sopenharmony_ciconst char *I18nTimeZone::TIMEZONE_ROOT_TAG = "timezones";
659596a2c1Sopenharmony_ciconst char *I18nTimeZone::TIMEZONE_SECOND_ROOT_TAG = "timezone";
669596a2c1Sopenharmony_ciconst char *I18nTimeZone::CITY_DISPLAYNAME_ROOT_TAG = "display_names";
679596a2c1Sopenharmony_ciconst char *I18nTimeZone::CITY_DISPLAYNAME_SECOND_ROOT_TAG = "display_name";
689596a2c1Sopenharmony_ci
699596a2c1Sopenharmony_cistd::set<std::string> I18nTimeZone::supportedLocales {};
709596a2c1Sopenharmony_cistd::set<std::string> I18nTimeZone::availableZoneCityIDs {};
719596a2c1Sopenharmony_cistd::map<std::string, std::string> I18nTimeZone::city2TimeZoneID {};
729596a2c1Sopenharmony_cistd::map<std::string, std::string> I18nTimeZone::BEST_MATCH_LOCALE {};
739596a2c1Sopenharmony_cistd::mutex I18nTimeZone::cityTimeZoneMutex;
749596a2c1Sopenharmony_cistd::mutex I18nTimeZone::matchLocaleMutex;
759596a2c1Sopenharmony_ci
769596a2c1Sopenharmony_ciconst int RECV_CHAR_LEN = 128;
779596a2c1Sopenharmony_ci
789596a2c1Sopenharmony_cistd::map<int, std::string> I18nTimeZone::categoryNum2TimezoneWN {
799596a2c1Sopenharmony_ci    { 0, "Africa/Abidjan" },
809596a2c1Sopenharmony_ci    { 1, "Africa/Accra" },
819596a2c1Sopenharmony_ci    { 2, "Africa/Algiers" },
829596a2c1Sopenharmony_ci    { 3, "Africa/Bamako" },
839596a2c1Sopenharmony_ci    { 4, "Africa/Banjul" },
849596a2c1Sopenharmony_ci    { 5, "Africa/Bissau" },
859596a2c1Sopenharmony_ci    { 6, "Africa/Casablanca" },
869596a2c1Sopenharmony_ci    { 7, "Africa/Ceuta" },
879596a2c1Sopenharmony_ci    { 8, "Africa/Conakry" },
889596a2c1Sopenharmony_ci    { 9, "Africa/Dakar" },
899596a2c1Sopenharmony_ci    { 10, "Africa/El_Aaiun" },
909596a2c1Sopenharmony_ci    { 11, "Africa/Freetown" },
919596a2c1Sopenharmony_ci    { 12, "Africa/Lome" },
929596a2c1Sopenharmony_ci    { 13, "Africa/Monrovia" },
939596a2c1Sopenharmony_ci    { 14, "Africa/Nouakchott" },
949596a2c1Sopenharmony_ci    { 15, "Africa/Ouagadougou" },
959596a2c1Sopenharmony_ci    { 16, "America/Adak" },
969596a2c1Sopenharmony_ci    { 17, "America/Anchorage" },
979596a2c1Sopenharmony_ci    { 18, "America/Anguilla" },
989596a2c1Sopenharmony_ci    { 19, "America/Antigua" },
999596a2c1Sopenharmony_ci    { 20, "America/Aruba" },
1009596a2c1Sopenharmony_ci    { 21, "America/Atikokan" },
1019596a2c1Sopenharmony_ci    { 22, "America/Bahia_Banderas" },
1029596a2c1Sopenharmony_ci    { 23, "America/Barbados" },
1039596a2c1Sopenharmony_ci    { 24, "America/Belem" },
1049596a2c1Sopenharmony_ci    { 25, "America/Belize" },
1059596a2c1Sopenharmony_ci    { 26, "America/Blanc-Sablon" },
1069596a2c1Sopenharmony_ci    { 27, "America/Boa_Vista" },
1079596a2c1Sopenharmony_ci    { 28, "America/Bogota" },
1089596a2c1Sopenharmony_ci    { 29, "America/Boise" },
1099596a2c1Sopenharmony_ci    { 30, "America/Cambridge_Bay" },
1109596a2c1Sopenharmony_ci    { 31, "America/Cancun" },
1119596a2c1Sopenharmony_ci    { 32, "America/Caracas" },
1129596a2c1Sopenharmony_ci    { 33, "America/Cayenne" },
1139596a2c1Sopenharmony_ci    { 34, "America/Cayman" },
1149596a2c1Sopenharmony_ci    { 35, "America/Chicago" },
1159596a2c1Sopenharmony_ci    { 36, "America/Chihuahua" },
1169596a2c1Sopenharmony_ci    { 37, "America/Mexico_City" }, // old data is 'America/Ciudad_Juarez'
1179596a2c1Sopenharmony_ci    { 38, "America/Costa_Rica" },
1189596a2c1Sopenharmony_ci    { 39, "America/Creston" },
1199596a2c1Sopenharmony_ci    { 40, "America/Curacao" },
1209596a2c1Sopenharmony_ci    { 41, "America/Danmarkshavn" },
1219596a2c1Sopenharmony_ci    { 42, "America/Dawson" },
1229596a2c1Sopenharmony_ci    { 43, "America/Dawson_Creek" },
1239596a2c1Sopenharmony_ci    { 44, "America/Denver" },
1249596a2c1Sopenharmony_ci    { 45, "America/Detroit" },
1259596a2c1Sopenharmony_ci    { 46, "America/Dominica" },
1269596a2c1Sopenharmony_ci    { 47, "America/Edmonton" },
1279596a2c1Sopenharmony_ci    { 48, "America/El_Salvador" },
1289596a2c1Sopenharmony_ci    { 49, "America/Fort_Nelson" },
1299596a2c1Sopenharmony_ci    { 50, "America/Glace_Bay" },
1309596a2c1Sopenharmony_ci    { 51, "America/Goose_Bay" },
1319596a2c1Sopenharmony_ci    { 52, "America/Grand_Turk" },
1329596a2c1Sopenharmony_ci    { 53, "America/Grenada" },
1339596a2c1Sopenharmony_ci    { 54, "America/Guadeloupe" },
1349596a2c1Sopenharmony_ci    { 55, "America/Guatemala" },
1359596a2c1Sopenharmony_ci    { 56, "America/Guayaquil" },
1369596a2c1Sopenharmony_ci    { 57, "America/Guyana" },
1379596a2c1Sopenharmony_ci    { 58, "America/Halifax" },
1389596a2c1Sopenharmony_ci    { 59, "America/Havana" },
1399596a2c1Sopenharmony_ci    { 60, "America/Hermosillo" },
1409596a2c1Sopenharmony_ci    { 61, "America/Indiana/Indianapolis" },
1419596a2c1Sopenharmony_ci    { 62, "America/Indiana/Knox" },
1429596a2c1Sopenharmony_ci    { 63, "America/Indiana/Marengo" },
1439596a2c1Sopenharmony_ci    { 64, "America/Indiana/Petersburg" },
1449596a2c1Sopenharmony_ci    { 65, "America/Indiana/Tell_City" },
1459596a2c1Sopenharmony_ci    { 66, "America/Indiana/Vevay" },
1469596a2c1Sopenharmony_ci    { 67, "America/Indiana/Vincennes" },
1479596a2c1Sopenharmony_ci    { 68, "America/Indiana/Winamac" },
1489596a2c1Sopenharmony_ci    { 69, "America/Inuvik" },
1499596a2c1Sopenharmony_ci    { 70, "America/Iqaluit" },
1509596a2c1Sopenharmony_ci    { 71, "America/Jamaica" },
1519596a2c1Sopenharmony_ci    { 72, "America/Juneau" },
1529596a2c1Sopenharmony_ci    { 73, "America/Kentucky/Louisville" },
1539596a2c1Sopenharmony_ci    { 74, "America/Kentucky/Monticello" },
1549596a2c1Sopenharmony_ci    { 75, "America/Kralendijk" },
1559596a2c1Sopenharmony_ci    { 76, "America/Los_Angeles" },
1569596a2c1Sopenharmony_ci    { 77, "America/Lower_Princes" },
1579596a2c1Sopenharmony_ci    { 78, "America/Managua" },
1589596a2c1Sopenharmony_ci    { 79, "America/Manaus" },
1599596a2c1Sopenharmony_ci    { 80, "America/Marigot" },
1609596a2c1Sopenharmony_ci    { 81, "America/Martinique" },
1619596a2c1Sopenharmony_ci    { 82, "America/Matamoros" },
1629596a2c1Sopenharmony_ci    { 83, "America/Mazatlan" },
1639596a2c1Sopenharmony_ci    { 84, "America/Menominee" },
1649596a2c1Sopenharmony_ci    { 85, "America/Merida" },
1659596a2c1Sopenharmony_ci    { 86, "America/Metlakatla" },
1669596a2c1Sopenharmony_ci    { 87, "America/Mexico_City" },
1679596a2c1Sopenharmony_ci    { 88, "America/Miquelon" },
1689596a2c1Sopenharmony_ci    { 89, "America/Moncton" },
1699596a2c1Sopenharmony_ci    { 90, "America/Monterrey" },
1709596a2c1Sopenharmony_ci    { 91, "America/Montserrat" },
1719596a2c1Sopenharmony_ci    { 92, "America/Nassau" },
1729596a2c1Sopenharmony_ci    { 93, "America/New_York" },
1739596a2c1Sopenharmony_ci    { 94, "America/Nome" },
1749596a2c1Sopenharmony_ci    { 95, "America/Noronha" },
1759596a2c1Sopenharmony_ci    { 96, "America/North_Dakota/Beulah" },
1769596a2c1Sopenharmony_ci    { 97, "America/North_Dakota/Center" },
1779596a2c1Sopenharmony_ci    { 98, "America/North_Dakota/New_Salem" },
1789596a2c1Sopenharmony_ci    { 99, "America/Nuuk" },
1799596a2c1Sopenharmony_ci    { 100, "America/Ojinaga" },
1809596a2c1Sopenharmony_ci    { 101, "America/Panama" },
1819596a2c1Sopenharmony_ci    { 102, "America/Paramaribo" },
1829596a2c1Sopenharmony_ci    { 103, "America/Phoenix" },
1839596a2c1Sopenharmony_ci    { 104, "America/Port-au-Prince" },
1849596a2c1Sopenharmony_ci    { 105, "America/Port_of_Spain" },
1859596a2c1Sopenharmony_ci    { 106, "America/Puerto_Rico" },
1869596a2c1Sopenharmony_ci    { 107, "America/Rankin_Inlet" },
1879596a2c1Sopenharmony_ci    { 108, "America/Regina" },
1889596a2c1Sopenharmony_ci    { 109, "America/Resolute" },
1899596a2c1Sopenharmony_ci    { 110, "America/Santarem" },
1909596a2c1Sopenharmony_ci    { 111, "America/Santo_Domingo" },
1919596a2c1Sopenharmony_ci    { 112, "America/Scoresbysund" },
1929596a2c1Sopenharmony_ci    { 113, "America/Sitka" },
1939596a2c1Sopenharmony_ci    { 114, "America/St_Barthelemy" },
1949596a2c1Sopenharmony_ci    { 115, "America/St_Johns" },
1959596a2c1Sopenharmony_ci    { 116, "America/St_Kitts" },
1969596a2c1Sopenharmony_ci    { 117, "America/St_Lucia" },
1979596a2c1Sopenharmony_ci    { 118, "America/St_Thomas" },
1989596a2c1Sopenharmony_ci    { 119, "America/St_Vincent" },
1999596a2c1Sopenharmony_ci    { 120, "America/Swift_Current" },
2009596a2c1Sopenharmony_ci    { 121, "America/Tegucigalpa" },
2019596a2c1Sopenharmony_ci    { 122, "America/Thule" },
2029596a2c1Sopenharmony_ci    { 123, "America/Tijuana" },
2039596a2c1Sopenharmony_ci    { 124, "America/Toronto" },
2049596a2c1Sopenharmony_ci    { 125, "America/Tortola" },
2059596a2c1Sopenharmony_ci    { 126, "America/Vancouver" },
2069596a2c1Sopenharmony_ci    { 127, "America/Whitehorse" },
2079596a2c1Sopenharmony_ci    { 128, "America/Winnipeg" },
2089596a2c1Sopenharmony_ci    { 129, "America/Yakutat" },
2099596a2c1Sopenharmony_ci    { 130, "Asia/Anadyr" },
2109596a2c1Sopenharmony_ci    { 131, "Atlantic/Azores" },
2119596a2c1Sopenharmony_ci    { 132, "Atlantic/Bermuda" },
2129596a2c1Sopenharmony_ci    { 133, "Atlantic/Canary" },
2139596a2c1Sopenharmony_ci    { 134, "Atlantic/Cape_Verde" },
2149596a2c1Sopenharmony_ci    { 135, "Atlantic/Faroe" },
2159596a2c1Sopenharmony_ci    { 136, "Atlantic/Madeira" },
2169596a2c1Sopenharmony_ci    { 137, "Atlantic/Reykjavik" },
2179596a2c1Sopenharmony_ci    { 138, "Etc/GMT" },
2189596a2c1Sopenharmony_ci    { 139, "Etc/GMT+1" },
2199596a2c1Sopenharmony_ci    { 140, "Etc/GMT+10" },
2209596a2c1Sopenharmony_ci    { 141, "Etc/GMT+11" },
2219596a2c1Sopenharmony_ci    { 142, "Etc/GMT+12" },
2229596a2c1Sopenharmony_ci    { 143, "Etc/GMT+2" },
2239596a2c1Sopenharmony_ci    { 144, "Etc/GMT+3" },
2249596a2c1Sopenharmony_ci    { 145, "Etc/GMT+4" },
2259596a2c1Sopenharmony_ci    { 146, "Etc/GMT+5" },
2269596a2c1Sopenharmony_ci    { 147, "Etc/GMT+6" },
2279596a2c1Sopenharmony_ci    { 148, "Etc/GMT+7" },
2289596a2c1Sopenharmony_ci    { 149, "Etc/GMT+8" },
2299596a2c1Sopenharmony_ci    { 150, "Etc/GMT+9" },
2309596a2c1Sopenharmony_ci    { 151, "Etc/GMT-12" },
2319596a2c1Sopenharmony_ci    { 152, "Europe/Dublin" },
2329596a2c1Sopenharmony_ci    { 153, "Europe/Gibraltar" },
2339596a2c1Sopenharmony_ci    { 154, "Europe/Guernsey" },
2349596a2c1Sopenharmony_ci    { 155, "Europe/Isle_of_Man" },
2359596a2c1Sopenharmony_ci    { 156, "Europe/Jersey" },
2369596a2c1Sopenharmony_ci    { 157, "Europe/Lisbon" },
2379596a2c1Sopenharmony_ci    { 158, "Europe/London" },
2389596a2c1Sopenharmony_ci    { 159, "Europe/Madrid" },
2399596a2c1Sopenharmony_ci    { 160, "Europe/Oslo" },
2409596a2c1Sopenharmony_ci    { 161, "Europe/Paris" },
2419596a2c1Sopenharmony_ci    { 162, "Pacific/Galapagos" },
2429596a2c1Sopenharmony_ci    { 163, "Pacific/Honolulu" },
2439596a2c1Sopenharmony_ci    { 164, "Pacific/Kiritimati" },
2449596a2c1Sopenharmony_ci    { 165, "Pacific/Midway" },
2459596a2c1Sopenharmony_ci};
2469596a2c1Sopenharmony_cistd::map<int, std::string> I18nTimeZone::categoryNum2TimezoneEN {
2479596a2c1Sopenharmony_ci    { 0, "Africa/Accra" },
2489596a2c1Sopenharmony_ci    { 1, "Africa/Addis_Ababa" },
2499596a2c1Sopenharmony_ci    { 2, "Africa/Algiers" },
2509596a2c1Sopenharmony_ci    { 3, "Africa/Asmara" },
2519596a2c1Sopenharmony_ci    { 4, "Africa/Bamako" },
2529596a2c1Sopenharmony_ci    { 5, "Africa/Bangui" },
2539596a2c1Sopenharmony_ci    { 6, "Africa/Brazzaville" },
2549596a2c1Sopenharmony_ci    { 7, "Africa/Cairo" },
2559596a2c1Sopenharmony_ci    { 8, "Africa/Djibouti" },
2569596a2c1Sopenharmony_ci    { 9, "Africa/Douala" },
2579596a2c1Sopenharmony_ci    { 10, "Africa/Juba" },
2589596a2c1Sopenharmony_ci    { 11, "Africa/Kampala" },
2599596a2c1Sopenharmony_ci    { 12, "Africa/Khartoum" },
2609596a2c1Sopenharmony_ci    { 13, "Africa/Kinshasa" },
2619596a2c1Sopenharmony_ci    { 14, "Africa/Lagos" },
2629596a2c1Sopenharmony_ci    { 15, "Africa/Libreville" },
2639596a2c1Sopenharmony_ci    { 16, "Africa/Lome" },
2649596a2c1Sopenharmony_ci    { 17, "Africa/Lubumbashi" },
2659596a2c1Sopenharmony_ci    { 18, "Africa/Malabo" },
2669596a2c1Sopenharmony_ci    { 19, "Africa/Mogadishu" },
2679596a2c1Sopenharmony_ci    { 20, "Africa/Nairobi" },
2689596a2c1Sopenharmony_ci    { 21, "Africa/Ndjamena" },
2699596a2c1Sopenharmony_ci    { 22, "Africa/Niamey" },
2709596a2c1Sopenharmony_ci    { 23, "Africa/Ouagadougou" },
2719596a2c1Sopenharmony_ci    { 24, "Africa/Porto-Novo" },
2729596a2c1Sopenharmony_ci    { 25, "Africa/Sao_Tome" },
2739596a2c1Sopenharmony_ci    { 26, "Africa/Tripoli" },
2749596a2c1Sopenharmony_ci    { 27, "Africa/Tunis" },
2759596a2c1Sopenharmony_ci    { 28, "America/Adak" },
2769596a2c1Sopenharmony_ci    { 29, "Arctic/Longyearbyen" },
2779596a2c1Sopenharmony_ci    { 30, "Asia/Aden" },
2789596a2c1Sopenharmony_ci    { 31, "Asia/Almaty" },
2799596a2c1Sopenharmony_ci    { 32, "Asia/Amman" },
2809596a2c1Sopenharmony_ci    { 33, "Asia/Anadyr" },
2819596a2c1Sopenharmony_ci    { 34, "Asia/Aqtau" },
2829596a2c1Sopenharmony_ci    { 35, "Asia/Aqtobe" },
2839596a2c1Sopenharmony_ci    { 36, "Asia/Ashgabat" },
2849596a2c1Sopenharmony_ci    { 37, "Asia/Atyrau" },
2859596a2c1Sopenharmony_ci    { 38, "Asia/Baghdad" },
2869596a2c1Sopenharmony_ci    { 39, "Asia/Bahrain" },
2879596a2c1Sopenharmony_ci    { 40, "Asia/Baku" },
2889596a2c1Sopenharmony_ci    { 41, "Asia/Bangkok" },
2899596a2c1Sopenharmony_ci    { 42, "Asia/Barnaul" },
2909596a2c1Sopenharmony_ci    { 43, "Asia/Beirut" },
2919596a2c1Sopenharmony_ci    { 44, "Asia/Bishkek" },
2929596a2c1Sopenharmony_ci    { 45, "Asia/Brunei" },
2939596a2c1Sopenharmony_ci    { 46, "Asia/Chita" },
2949596a2c1Sopenharmony_ci    { 47, "Asia/Choibalsan" },
2959596a2c1Sopenharmony_ci    { 48, "Asia/Colombo" },
2969596a2c1Sopenharmony_ci    { 49, "Asia/Damascus" },
2979596a2c1Sopenharmony_ci    { 50, "Asia/Dhaka" },
2989596a2c1Sopenharmony_ci    { 51, "Asia/Dubai" },
2999596a2c1Sopenharmony_ci    { 52, "Asia/Dushanbe" },
3009596a2c1Sopenharmony_ci    { 53, "Asia/Famagusta" },
3019596a2c1Sopenharmony_ci    { 54, "Asia/Gaza" },
3029596a2c1Sopenharmony_ci    { 55, "Asia/Hebron" },
3039596a2c1Sopenharmony_ci    { 56, "Asia/Ho_Chi_Minh" },
3049596a2c1Sopenharmony_ci    { 57, "Asia/Hong_Kong" },
3059596a2c1Sopenharmony_ci    { 58, "Asia/Hovd" },
3069596a2c1Sopenharmony_ci    { 59, "Asia/Irkutsk" },
3079596a2c1Sopenharmony_ci    { 60, "Asia/Jakarta" },
3089596a2c1Sopenharmony_ci    { 61, "Asia/Jayapura" },
3099596a2c1Sopenharmony_ci    { 62, "Asia/Jerusalem" },
3109596a2c1Sopenharmony_ci    { 63, "Asia/Kabul" },
3119596a2c1Sopenharmony_ci    { 64, "Asia/Kamchatka" },
3129596a2c1Sopenharmony_ci    { 65, "Asia/Karachi" },
3139596a2c1Sopenharmony_ci    { 66, "Asia/Kathmandu" },
3149596a2c1Sopenharmony_ci    { 67, "Asia/Khandyga" },
3159596a2c1Sopenharmony_ci    { 68, "Asia/Kolkata" },
3169596a2c1Sopenharmony_ci    { 69, "Asia/Krasnoyarsk" },
3179596a2c1Sopenharmony_ci    { 70, "Asia/Kuala_Lumpur" },
3189596a2c1Sopenharmony_ci    { 71, "Asia/Kuching" },
3199596a2c1Sopenharmony_ci    { 72, "Asia/Kuwait" },
3209596a2c1Sopenharmony_ci    { 73, "Asia/Macau" },
3219596a2c1Sopenharmony_ci    { 74, "Asia/Magadan" },
3229596a2c1Sopenharmony_ci    { 75, "Asia/Makassar" },
3239596a2c1Sopenharmony_ci    { 76, "Asia/Manila" },
3249596a2c1Sopenharmony_ci    { 77, "Asia/Muscat" },
3259596a2c1Sopenharmony_ci    { 78, "Asia/Nicosia" },
3269596a2c1Sopenharmony_ci    { 79, "Asia/Novokuznetsk" },
3279596a2c1Sopenharmony_ci    { 80, "Asia/Novosibirsk" },
3289596a2c1Sopenharmony_ci    { 81, "Asia/Omsk" },
3299596a2c1Sopenharmony_ci    { 82, "Asia/Oral" },
3309596a2c1Sopenharmony_ci    { 83, "Asia/Phnom_Penh" },
3319596a2c1Sopenharmony_ci    { 84, "Asia/Pontianak" },
3329596a2c1Sopenharmony_ci    { 85, "Asia/Pyongyang" },
3339596a2c1Sopenharmony_ci    { 86, "Asia/Qatar" },
3349596a2c1Sopenharmony_ci    { 87, "Asia/Qostanay" },
3359596a2c1Sopenharmony_ci    { 88, "Asia/Qyzylorda" },
3369596a2c1Sopenharmony_ci    { 89, "Asia/Riyadh" },
3379596a2c1Sopenharmony_ci    { 90, "Asia/Sakhalin" },
3389596a2c1Sopenharmony_ci    { 91, "Asia/Samarkand" },
3399596a2c1Sopenharmony_ci    { 92, "Asia/Seoul" },
3409596a2c1Sopenharmony_ci    { 93, "Asia/Shanghai" },
3419596a2c1Sopenharmony_ci    { 94, "Asia/Singapore" },
3429596a2c1Sopenharmony_ci    { 95, "Asia/Srednekolymsk" },
3439596a2c1Sopenharmony_ci    { 96, "Asia/Taipei" },
3449596a2c1Sopenharmony_ci    { 97, "Asia/Tashkent" },
3459596a2c1Sopenharmony_ci    { 98, "Asia/Tbilisi" },
3469596a2c1Sopenharmony_ci    { 99, "Asia/Tehran" },
3479596a2c1Sopenharmony_ci    { 100, "Asia/Thimbu" },
3489596a2c1Sopenharmony_ci    { 101, "Asia/Tokyo" },
3499596a2c1Sopenharmony_ci    { 102, "Asia/Tomsk" },
3509596a2c1Sopenharmony_ci    { 103, "Asia/Ulaanbaatar" },
3519596a2c1Sopenharmony_ci    { 104, "Asia/Urumqi" },
3529596a2c1Sopenharmony_ci    { 105, "Asia/Ust-Nera" },
3539596a2c1Sopenharmony_ci    { 106, "Asia/Vientiane" },
3549596a2c1Sopenharmony_ci    { 107, "Asia/Vladivostok" },
3559596a2c1Sopenharmony_ci    { 108, "Asia/Yakutsk" },
3569596a2c1Sopenharmony_ci    { 109, "Asia/Yangon" },
3579596a2c1Sopenharmony_ci    { 110, "Asia/Yekaterinburg" },
3589596a2c1Sopenharmony_ci    { 111, "Asia/Yerevan" },
3599596a2c1Sopenharmony_ci    { 112, "Etc/GMT" },
3609596a2c1Sopenharmony_ci    { 113, "Etc/GMT-1" },
3619596a2c1Sopenharmony_ci    { 114, "Etc/GMT-10" },
3629596a2c1Sopenharmony_ci    { 115, "Etc/GMT-11" },
3639596a2c1Sopenharmony_ci    { 116, "Etc/GMT-12" },
3649596a2c1Sopenharmony_ci    { 117, "Etc/GMT-2" },
3659596a2c1Sopenharmony_ci    { 118, "Etc/GMT-3" },
3669596a2c1Sopenharmony_ci    { 119, "Etc/GMT-4" },
3679596a2c1Sopenharmony_ci    { 120, "Etc/GMT-5" },
3689596a2c1Sopenharmony_ci    { 121, "Etc/GMT-6" },
3699596a2c1Sopenharmony_ci    { 122, "Etc/GMT-7" },
3709596a2c1Sopenharmony_ci    { 123, "Etc/GMT-8" },
3719596a2c1Sopenharmony_ci    { 124, "Etc/GMT-9" },
3729596a2c1Sopenharmony_ci    { 125, "Europe/Amsterdam" },
3739596a2c1Sopenharmony_ci    { 126, "Europe/Andorra" },
3749596a2c1Sopenharmony_ci    { 127, "Europe/Astrakhan" },
3759596a2c1Sopenharmony_ci    { 128, "Europe/Athens" },
3769596a2c1Sopenharmony_ci    { 129, "Europe/Belgrade" },
3779596a2c1Sopenharmony_ci    { 130, "Europe/Berlin" },
3789596a2c1Sopenharmony_ci    { 131, "Europe/Bratislava" },
3799596a2c1Sopenharmony_ci    { 132, "Europe/Brussels" },
3809596a2c1Sopenharmony_ci    { 133, "Europe/Bucharest" },
3819596a2c1Sopenharmony_ci    { 134, "Europe/Budapest" },
3829596a2c1Sopenharmony_ci    { 135, "Europe/Busingen" },
3839596a2c1Sopenharmony_ci    { 136, "Europe/Chisinau" },
3849596a2c1Sopenharmony_ci    { 137, "Europe/Copenhagen" },
3859596a2c1Sopenharmony_ci    { 138, "Europe/Helsinki" },
3869596a2c1Sopenharmony_ci    { 139, "Europe/Istanbul" },
3879596a2c1Sopenharmony_ci    { 140, "Europe/Kaliningrad" },
3889596a2c1Sopenharmony_ci    { 141, "Europe/Kirov" },
3899596a2c1Sopenharmony_ci    { 142, "Europe/Kiev" },
3909596a2c1Sopenharmony_ci    { 143, "Europe/Ljubljana" },
3919596a2c1Sopenharmony_ci    { 144, "Europe/London" },
3929596a2c1Sopenharmony_ci    { 145, "Europe/Luxembourg" },
3939596a2c1Sopenharmony_ci    { 146, "Europe/Madrid" },
3949596a2c1Sopenharmony_ci    { 147, "Europe/Malta" },
3959596a2c1Sopenharmony_ci    { 148, "Europe/Mariehamn" },
3969596a2c1Sopenharmony_ci    { 149, "Europe/Minsk" },
3979596a2c1Sopenharmony_ci    { 150, "Europe/Monaco" },
3989596a2c1Sopenharmony_ci    { 151, "Europe/Moscow" },
3999596a2c1Sopenharmony_ci    { 152, "Europe/Oslo" },
4009596a2c1Sopenharmony_ci    { 153, "Europe/Paris" },
4019596a2c1Sopenharmony_ci    { 154, "Europe/Podgorica" },
4029596a2c1Sopenharmony_ci    { 155, "Europe/Prague" },
4039596a2c1Sopenharmony_ci    { 156, "Europe/Riga" },
4049596a2c1Sopenharmony_ci    { 157, "Europe/Rome" },
4059596a2c1Sopenharmony_ci    { 158, "Europe/Samara" },
4069596a2c1Sopenharmony_ci    { 159, "Europe/San_Marino" },
4079596a2c1Sopenharmony_ci    { 160, "Europe/Sarajevo" },
4089596a2c1Sopenharmony_ci    { 161, "Europe/Saratov" },
4099596a2c1Sopenharmony_ci    { 162, "Europe/Simferopol" },
4109596a2c1Sopenharmony_ci    { 163, "Europe/Skopje" },
4119596a2c1Sopenharmony_ci    { 164, "Europe/Sofia" },
4129596a2c1Sopenharmony_ci    { 165, "Europe/Stockholm" },
4139596a2c1Sopenharmony_ci    { 166, "Europe/Tallinn" },
4149596a2c1Sopenharmony_ci    { 167, "Europe/Tirane" },
4159596a2c1Sopenharmony_ci    { 168, "Europe/Ulyanovsk" },
4169596a2c1Sopenharmony_ci    { 169, "Europe/Vaduz" },
4179596a2c1Sopenharmony_ci    { 170, "Europe/Vienna" },
4189596a2c1Sopenharmony_ci    { 171, "Europe/Vilnius" },
4199596a2c1Sopenharmony_ci    { 172, "Europe/Volgograd" },
4209596a2c1Sopenharmony_ci    { 173, "Europe/Warsaw" },
4219596a2c1Sopenharmony_ci    { 174, "Europe/Zagreb" },
4229596a2c1Sopenharmony_ci    { 175, "Europe/Zurich" },
4239596a2c1Sopenharmony_ci    { 176, "Indian/Maldives" },
4249596a2c1Sopenharmony_ci    { 177, "Pacific/Chuuk" },
4259596a2c1Sopenharmony_ci    { 178, "Pacific/Guam" },
4269596a2c1Sopenharmony_ci    { 179, "Pacific/Kosrae" },
4279596a2c1Sopenharmony_ci    { 180, "Pacific/Kwajalein" },
4289596a2c1Sopenharmony_ci    { 181, "Pacific/Majuro" },
4299596a2c1Sopenharmony_ci    { 182, "Pacific/Palau" },
4309596a2c1Sopenharmony_ci    { 183, "Pacific/Pohnpei" },
4319596a2c1Sopenharmony_ci    { 184, "Pacific/Saipan" },
4329596a2c1Sopenharmony_ci    { 185, "Pacific/Tarawa" },
4339596a2c1Sopenharmony_ci    { 186, "Pacific/Wake" },
4349596a2c1Sopenharmony_ci};
4359596a2c1Sopenharmony_cistd::map<int, std::string> I18nTimeZone::categoryNum2TimezoneWS {
4369596a2c1Sopenharmony_ci    { 0, "Africa/Johannesburg" },
4379596a2c1Sopenharmony_ci    { 1, "America/Araguaina" },
4389596a2c1Sopenharmony_ci    { 2, "America/Argentina/Buenos_Aires" },
4399596a2c1Sopenharmony_ci    { 3, "America/Argentina/Catamarca" },
4409596a2c1Sopenharmony_ci    { 4, "America/Argentina/Cordoba" },
4419596a2c1Sopenharmony_ci    { 5, "America/Argentina/Jujuy" },
4429596a2c1Sopenharmony_ci    { 6, "America/Argentina/La_Rioja" },
4439596a2c1Sopenharmony_ci    { 7, "America/Argentina/Mendoza" },
4449596a2c1Sopenharmony_ci    { 8, "America/Argentina/Rio_Gallegos" },
4459596a2c1Sopenharmony_ci    { 9, "America/Argentina/Salta" },
4469596a2c1Sopenharmony_ci    { 10, "America/Argentina/San_Juan" },
4479596a2c1Sopenharmony_ci    { 11, "America/Argentina/San_Luis" },
4489596a2c1Sopenharmony_ci    { 12, "America/Argentina/Tucuman" },
4499596a2c1Sopenharmony_ci    { 13, "America/Argentina/Ushuaia" },
4509596a2c1Sopenharmony_ci    { 14, "America/Asuncion" },
4519596a2c1Sopenharmony_ci    { 15, "America/Bahia" },
4529596a2c1Sopenharmony_ci    { 16, "America/Belem" },
4539596a2c1Sopenharmony_ci    { 17, "America/Boa_Vista" },
4549596a2c1Sopenharmony_ci    { 18, "America/Bogota" },
4559596a2c1Sopenharmony_ci    { 19, "America/Campo_Grande" },
4569596a2c1Sopenharmony_ci    { 20, "America/Cuiaba" },
4579596a2c1Sopenharmony_ci    { 21, "America/Eirunepe" },
4589596a2c1Sopenharmony_ci    { 22, "America/Fortaleza" },
4599596a2c1Sopenharmony_ci    { 23, "America/Guayaquil" },
4609596a2c1Sopenharmony_ci    { 24, "America/La_Paz" },
4619596a2c1Sopenharmony_ci    { 25, "America/Lima" },
4629596a2c1Sopenharmony_ci    { 26, "America/Maceio" },
4639596a2c1Sopenharmony_ci    { 27, "America/Manaus" },
4649596a2c1Sopenharmony_ci    { 28, "America/Montevideo" },
4659596a2c1Sopenharmony_ci    { 29, "America/Noronha" },
4669596a2c1Sopenharmony_ci    { 30, "America/Porto_Velho" },
4679596a2c1Sopenharmony_ci    { 31, "America/Punta_Arenas" },
4689596a2c1Sopenharmony_ci    { 32, "America/Recife" },
4699596a2c1Sopenharmony_ci    { 33, "America/Rio_Branco" },
4709596a2c1Sopenharmony_ci    { 34, "America/Santarem" },
4719596a2c1Sopenharmony_ci    { 35, "America/Santiago" },
4729596a2c1Sopenharmony_ci    { 36, "America/Sao_Paulo" },
4739596a2c1Sopenharmony_ci    { 37, "Antarctica/McMurdo" },
4749596a2c1Sopenharmony_ci    { 38, "Antarctica/Palmer" },
4759596a2c1Sopenharmony_ci    { 39, "Antarctica/Rothera" },
4769596a2c1Sopenharmony_ci    { 40, "Atlantic/South_Georgia" },
4779596a2c1Sopenharmony_ci    { 41, "Atlantic/St_Helena" },
4789596a2c1Sopenharmony_ci    { 42, "Atlantic/Stanley" },
4799596a2c1Sopenharmony_ci    { 43, "Etc/GMT" },
4809596a2c1Sopenharmony_ci    { 44, "Etc/GMT+1" },
4819596a2c1Sopenharmony_ci    { 45, "Etc/GMT+10" },
4829596a2c1Sopenharmony_ci    { 46, "Etc/GMT+11" },
4839596a2c1Sopenharmony_ci    { 47, "Etc/GMT+12" },
4849596a2c1Sopenharmony_ci    { 48, "Etc/GMT+2" },
4859596a2c1Sopenharmony_ci    { 49, "Etc/GMT+3" },
4869596a2c1Sopenharmony_ci    { 50, "Etc/GMT+4" },
4879596a2c1Sopenharmony_ci    { 51, "Etc/GMT+5" },
4889596a2c1Sopenharmony_ci    { 52, "Etc/GMT+6" },
4899596a2c1Sopenharmony_ci    { 53, "Etc/GMT+7" },
4909596a2c1Sopenharmony_ci    { 54, "Etc/GMT+8" },
4919596a2c1Sopenharmony_ci    { 55, "Etc/GMT+9" },
4929596a2c1Sopenharmony_ci    { 56, "Etc/GMT-12" },
4939596a2c1Sopenharmony_ci    { 57, "Etc/UTC" },
4949596a2c1Sopenharmony_ci    { 58, "Pacific/Apia" },
4959596a2c1Sopenharmony_ci    { 59, "Pacific/Auckland" },
4969596a2c1Sopenharmony_ci    { 60, "Pacific/Chatham" },
4979596a2c1Sopenharmony_ci    { 61, "Pacific/Easter" },
4989596a2c1Sopenharmony_ci    { 62, "Pacific/Fakaofo" },
4999596a2c1Sopenharmony_ci    { 63, "Pacific/Fiji" },
5009596a2c1Sopenharmony_ci    { 64, "Pacific/Funafuti" },
5019596a2c1Sopenharmony_ci    { 65, "Pacific/Galapagos" },
5029596a2c1Sopenharmony_ci    { 66, "Pacific/Gambier" },
5039596a2c1Sopenharmony_ci    { 67, "Pacific/Kanton" },
5049596a2c1Sopenharmony_ci    { 68, "Pacific/Kiritimati" },
5059596a2c1Sopenharmony_ci    { 69, "Pacific/Marquesas" },
5069596a2c1Sopenharmony_ci    { 70, "Pacific/Niue" },
5079596a2c1Sopenharmony_ci    { 71, "Pacific/Pago_Pago" },
5089596a2c1Sopenharmony_ci    { 72, "Pacific/Pitcairn" },
5099596a2c1Sopenharmony_ci    { 73, "Pacific/Rarotonga" },
5109596a2c1Sopenharmony_ci    { 74, "Pacific/Tahiti" },
5119596a2c1Sopenharmony_ci    { 75, "Pacific/Tongatapu" },
5129596a2c1Sopenharmony_ci    { 76, "Pacific/Wallis" },
5139596a2c1Sopenharmony_ci};
5149596a2c1Sopenharmony_cistd::map<int, std::string> I18nTimeZone::categoryNum2TimezoneES {
5159596a2c1Sopenharmony_ci    { 0, "Africa/Blantyre" },
5169596a2c1Sopenharmony_ci    { 1, "Africa/Brazzaville" },
5179596a2c1Sopenharmony_ci    { 2, "Africa/Bujumbura" },
5189596a2c1Sopenharmony_ci    { 3, "Africa/Dar_es_Salaam" },
5199596a2c1Sopenharmony_ci    { 4, "Africa/Gaborone" },
5209596a2c1Sopenharmony_ci    { 5, "Africa/Harare" },
5219596a2c1Sopenharmony_ci    { 6, "Africa/Johannesburg" },
5229596a2c1Sopenharmony_ci    { 7, "Africa/Kampala" },
5239596a2c1Sopenharmony_ci    { 8, "Africa/Kigali" },
5249596a2c1Sopenharmony_ci    { 9, "Africa/Kinshasa" },
5259596a2c1Sopenharmony_ci    { 10, "Africa/Libreville" },
5269596a2c1Sopenharmony_ci    { 11, "Africa/Luanda" },
5279596a2c1Sopenharmony_ci    { 12, "Africa/Lubumbashi" },
5289596a2c1Sopenharmony_ci    { 13, "Africa/Lusaka" },
5299596a2c1Sopenharmony_ci    { 14, "Africa/Malabo" },
5309596a2c1Sopenharmony_ci    { 15, "Africa/Maputo" },
5319596a2c1Sopenharmony_ci    { 16, "Africa/Maseru" },
5329596a2c1Sopenharmony_ci    { 17, "Africa/Mbabane" },
5339596a2c1Sopenharmony_ci    { 18, "Africa/Mogadishu" },
5349596a2c1Sopenharmony_ci    { 19, "Africa/Nairobi" },
5359596a2c1Sopenharmony_ci    { 20, "Africa/Sao_Tome" },
5369596a2c1Sopenharmony_ci    { 21, "Africa/Windhoek" },
5379596a2c1Sopenharmony_ci    { 22, "Antarctica/Casey" },
5389596a2c1Sopenharmony_ci    { 23, "Antarctica/Davis" },
5399596a2c1Sopenharmony_ci    { 24, "Antarctica/DumontDUrville" },
5409596a2c1Sopenharmony_ci    { 25, "Antarctica/Macquarie" },
5419596a2c1Sopenharmony_ci    { 26, "Antarctica/Mawson" },
5429596a2c1Sopenharmony_ci    { 27, "Antarctica/McMurdo" },
5439596a2c1Sopenharmony_ci    { 28, "Antarctica/Syowa" },
5449596a2c1Sopenharmony_ci    { 29, "Antarctica/Troll" },
5459596a2c1Sopenharmony_ci    { 30, "Antarctica/Vostok" },
5469596a2c1Sopenharmony_ci    { 31, "Asia/Dili" },
5479596a2c1Sopenharmony_ci    { 32, "Asia/Jakarta" },
5489596a2c1Sopenharmony_ci    { 33, "Asia/Jayapura" },
5499596a2c1Sopenharmony_ci    { 34, "Asia/Makassar" },
5509596a2c1Sopenharmony_ci    { 35, "Asia/Pontianak" },
5519596a2c1Sopenharmony_ci    { 36, "Australia/Adelaide" },
5529596a2c1Sopenharmony_ci    { 37, "Australia/Brisbane" },
5539596a2c1Sopenharmony_ci    { 38, "Australia/Broken_Hill" },
5549596a2c1Sopenharmony_ci    { 39, "Australia/Darwin" },
5559596a2c1Sopenharmony_ci    { 40, "Australia/Eucla" },
5569596a2c1Sopenharmony_ci    { 41, "Australia/Hobart" },
5579596a2c1Sopenharmony_ci    { 42, "Australia/Lindeman" },
5589596a2c1Sopenharmony_ci    { 43, "Australia/Lord_Howe" },
5599596a2c1Sopenharmony_ci    { 44, "Australia/Melbourne" },
5609596a2c1Sopenharmony_ci    { 45, "Australia/Perth" },
5619596a2c1Sopenharmony_ci    { 46, "Australia/Sydney" },
5629596a2c1Sopenharmony_ci    { 47, "Etc/GMT" },
5639596a2c1Sopenharmony_ci    { 48, "Etc/GMT-1" },
5649596a2c1Sopenharmony_ci    { 49, "Etc/GMT-10" },
5659596a2c1Sopenharmony_ci    { 50, "Etc/GMT-11" },
5669596a2c1Sopenharmony_ci    { 51, "Etc/GMT-12" },
5679596a2c1Sopenharmony_ci    { 52, "Etc/GMT-2" },
5689596a2c1Sopenharmony_ci    { 53, "Etc/GMT-3" },
5699596a2c1Sopenharmony_ci    { 54, "Etc/GMT-4" },
5709596a2c1Sopenharmony_ci    { 55, "Etc/GMT-5" },
5719596a2c1Sopenharmony_ci    { 56, "Etc/GMT-6" },
5729596a2c1Sopenharmony_ci    { 57, "Etc/GMT-7" },
5739596a2c1Sopenharmony_ci    { 58, "Etc/GMT-8" },
5749596a2c1Sopenharmony_ci    { 59, "Etc/GMT-9" },
5759596a2c1Sopenharmony_ci    { 60, "Indian/Antananarivo" },
5769596a2c1Sopenharmony_ci    { 61, "Indian/Chagos" },
5779596a2c1Sopenharmony_ci    { 62, "Indian/Christmas" },
5789596a2c1Sopenharmony_ci    { 63, "Indian/Cocos" },
5799596a2c1Sopenharmony_ci    { 64, "Indian/Comoro" },
5809596a2c1Sopenharmony_ci    { 65, "Indian/Kerguelen" },
5819596a2c1Sopenharmony_ci    { 66, "Indian/Mahe" },
5829596a2c1Sopenharmony_ci    { 67, "Indian/Maldives" },
5839596a2c1Sopenharmony_ci    { 68, "Indian/Mauritius" },
5849596a2c1Sopenharmony_ci    { 69, "Indian/Mayotte" },
5859596a2c1Sopenharmony_ci    { 70, "Indian/Reunion" },
5869596a2c1Sopenharmony_ci    { 71, "Pacific/Auckland" },
5879596a2c1Sopenharmony_ci    { 72, "Pacific/Bougainville" },
5889596a2c1Sopenharmony_ci    { 73, "Pacific/Efate" },
5899596a2c1Sopenharmony_ci    { 74, "Pacific/Fiji" },
5909596a2c1Sopenharmony_ci    { 75, "Pacific/Funafuti" },
5919596a2c1Sopenharmony_ci    { 76, "Pacific/Guadalcanal" },
5929596a2c1Sopenharmony_ci    { 77, "Pacific/Nauru" },
5939596a2c1Sopenharmony_ci    { 78, "Pacific/Norfolk" },
5949596a2c1Sopenharmony_ci    { 79, "Pacific/Noumea" },
5959596a2c1Sopenharmony_ci    { 80, "Pacific/Port_Moresby" },
5969596a2c1Sopenharmony_ci    { 81, "Pacific/Tarawa" },
5979596a2c1Sopenharmony_ci};
5989596a2c1Sopenharmony_ci
5999596a2c1Sopenharmony_ciI18nTimeZone::I18nTimeZone(std::string &id, bool isZoneID)
6009596a2c1Sopenharmony_ci{
6019596a2c1Sopenharmony_ci    if (isZoneID) {
6029596a2c1Sopenharmony_ci        if (id.empty()) {
6039596a2c1Sopenharmony_ci            std::string systemTimezone = ReadSystemParameter(TIMEZONE_KEY, SYS_PARAM_LEN);
6049596a2c1Sopenharmony_ci            if (systemTimezone.length() == 0) {
6059596a2c1Sopenharmony_ci                systemTimezone = DEFAULT_TIMEZONE;
6069596a2c1Sopenharmony_ci            }
6079596a2c1Sopenharmony_ci            icu::UnicodeString unicodeZoneID(systemTimezone.data(), systemTimezone.length());
6089596a2c1Sopenharmony_ci            timezone = icu::TimeZone::createTimeZone(unicodeZoneID);
6099596a2c1Sopenharmony_ci        } else {
6109596a2c1Sopenharmony_ci            icu::UnicodeString unicodeZoneID(id.data(), id.length());
6119596a2c1Sopenharmony_ci            timezone = icu::TimeZone::createTimeZone(unicodeZoneID);
6129596a2c1Sopenharmony_ci        }
6139596a2c1Sopenharmony_ci    } else {
6149596a2c1Sopenharmony_ci        if (city2TimeZoneID.size() == 0) {
6159596a2c1Sopenharmony_ci            GetAvailableZoneCityIDs();
6169596a2c1Sopenharmony_ci        }
6179596a2c1Sopenharmony_ci        if (city2TimeZoneID.find(id) == city2TimeZoneID.end()) {
6189596a2c1Sopenharmony_ci            timezone = icu::TimeZone::createDefault();
6199596a2c1Sopenharmony_ci        } else {
6209596a2c1Sopenharmony_ci            std::string timezoneID = city2TimeZoneID.at(id);
6219596a2c1Sopenharmony_ci            icu::UnicodeString unicodeZoneID(timezoneID.data(), timezoneID.length());
6229596a2c1Sopenharmony_ci            timezone = icu::TimeZone::createTimeZone(unicodeZoneID);
6239596a2c1Sopenharmony_ci        }
6249596a2c1Sopenharmony_ci    }
6259596a2c1Sopenharmony_ci}
6269596a2c1Sopenharmony_ci
6279596a2c1Sopenharmony_ciI18nTimeZone::~I18nTimeZone()
6289596a2c1Sopenharmony_ci{
6299596a2c1Sopenharmony_ci    if (timezone != nullptr) {
6309596a2c1Sopenharmony_ci        delete timezone;
6319596a2c1Sopenharmony_ci        timezone = nullptr;
6329596a2c1Sopenharmony_ci    }
6339596a2c1Sopenharmony_ci}
6349596a2c1Sopenharmony_ci
6359596a2c1Sopenharmony_ciicu::TimeZone* I18nTimeZone::GetTimeZone()
6369596a2c1Sopenharmony_ci{
6379596a2c1Sopenharmony_ci    return timezone;
6389596a2c1Sopenharmony_ci}
6399596a2c1Sopenharmony_ci
6409596a2c1Sopenharmony_cistd::unique_ptr<I18nTimeZone> I18nTimeZone::CreateInstance(std::string &id, bool isZoneID)
6419596a2c1Sopenharmony_ci{
6429596a2c1Sopenharmony_ci    std::unique_ptr<I18nTimeZone> i18nTimeZone = std::make_unique<I18nTimeZone>(id, isZoneID);
6439596a2c1Sopenharmony_ci    if (i18nTimeZone->GetTimeZone() == nullptr) {
6449596a2c1Sopenharmony_ci        return nullptr;
6459596a2c1Sopenharmony_ci    }
6469596a2c1Sopenharmony_ci    return i18nTimeZone;
6479596a2c1Sopenharmony_ci}
6489596a2c1Sopenharmony_ci
6499596a2c1Sopenharmony_ciint32_t I18nTimeZone::GetOffset(double date)
6509596a2c1Sopenharmony_ci{
6519596a2c1Sopenharmony_ci    int32_t rawOffset = 0;
6529596a2c1Sopenharmony_ci    int32_t dstOffset = 0;
6539596a2c1Sopenharmony_ci    bool local = false;
6549596a2c1Sopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
6559596a2c1Sopenharmony_ci    if (timezone == nullptr) {
6569596a2c1Sopenharmony_ci        return 0;
6579596a2c1Sopenharmony_ci    }
6589596a2c1Sopenharmony_ci    timezone->getOffset(date, (UBool)local, rawOffset, dstOffset, status);
6599596a2c1Sopenharmony_ci    if (U_FAILURE(status)) {
6609596a2c1Sopenharmony_ci        return 0;
6619596a2c1Sopenharmony_ci    }
6629596a2c1Sopenharmony_ci    return rawOffset + dstOffset;
6639596a2c1Sopenharmony_ci}
6649596a2c1Sopenharmony_ci
6659596a2c1Sopenharmony_ciint32_t I18nTimeZone::GetRawOffset()
6669596a2c1Sopenharmony_ci{
6679596a2c1Sopenharmony_ci    if (timezone == nullptr) {
6689596a2c1Sopenharmony_ci        return 0;
6699596a2c1Sopenharmony_ci    }
6709596a2c1Sopenharmony_ci    return timezone->getRawOffset();
6719596a2c1Sopenharmony_ci}
6729596a2c1Sopenharmony_ci
6739596a2c1Sopenharmony_cistd::string I18nTimeZone::GetID()
6749596a2c1Sopenharmony_ci{
6759596a2c1Sopenharmony_ci    if (timezone == nullptr) {
6769596a2c1Sopenharmony_ci        return "";
6779596a2c1Sopenharmony_ci    }
6789596a2c1Sopenharmony_ci    icu::UnicodeString zoneID;
6799596a2c1Sopenharmony_ci    timezone->getID(zoneID);
6809596a2c1Sopenharmony_ci    std::string result;
6819596a2c1Sopenharmony_ci    zoneID.toUTF8String(result);
6829596a2c1Sopenharmony_ci    return result;
6839596a2c1Sopenharmony_ci}
6849596a2c1Sopenharmony_ci
6859596a2c1Sopenharmony_cistd::string I18nTimeZone::GetDisplayName()
6869596a2c1Sopenharmony_ci{
6879596a2c1Sopenharmony_ci    if (timezone == nullptr) {
6889596a2c1Sopenharmony_ci        return "";
6899596a2c1Sopenharmony_ci    }
6909596a2c1Sopenharmony_ci    std::string localeStr = LocaleConfig::GetSystemLocale();
6919596a2c1Sopenharmony_ci    return GetDisplayName(localeStr, false);
6929596a2c1Sopenharmony_ci}
6939596a2c1Sopenharmony_ci
6949596a2c1Sopenharmony_cistd::string I18nTimeZone::GetDisplayName(bool isDST)
6959596a2c1Sopenharmony_ci{
6969596a2c1Sopenharmony_ci    std::string localeStr = LocaleConfig::GetSystemLocale();
6979596a2c1Sopenharmony_ci    return GetDisplayName(localeStr, isDST);
6989596a2c1Sopenharmony_ci}
6999596a2c1Sopenharmony_ci
7009596a2c1Sopenharmony_cistd::string I18nTimeZone::GetDisplayName(std::string localeStr)
7019596a2c1Sopenharmony_ci{
7029596a2c1Sopenharmony_ci    return GetDisplayName(localeStr, false);
7039596a2c1Sopenharmony_ci}
7049596a2c1Sopenharmony_ci
7059596a2c1Sopenharmony_cistd::string I18nTimeZone::GetDisplayName(
7069596a2c1Sopenharmony_ci    std::string localeStr, bool isDST)
7079596a2c1Sopenharmony_ci{
7089596a2c1Sopenharmony_ci    icu::TimeZone::EDisplayType style = icu::TimeZone::EDisplayType::LONG_GENERIC;
7099596a2c1Sopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
7109596a2c1Sopenharmony_ci    std::string systemLocale = LocaleConfig::GetSystemLocale();
7119596a2c1Sopenharmony_ci    icu::Locale locale = icu::Locale::forLanguageTag(systemLocale, status);
7129596a2c1Sopenharmony_ci    std::string result;
7139596a2c1Sopenharmony_ci    if (LocaleConfig::IsValidTag(localeStr)) {
7149596a2c1Sopenharmony_ci        locale = icu::Locale::forLanguageTag(localeStr, status);
7159596a2c1Sopenharmony_ci    }
7169596a2c1Sopenharmony_ci    if (U_FAILURE(status)) {
7179596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("create icu Locale for %{public}s failed.", localeStr.c_str());
7189596a2c1Sopenharmony_ci        return PseudoLocalizationProcessor(result);
7199596a2c1Sopenharmony_ci    }
7209596a2c1Sopenharmony_ci    icu::UnicodeString name;
7219596a2c1Sopenharmony_ci    timezone->getDisplayName((UBool)isDST, style, locale, name);
7229596a2c1Sopenharmony_ci    name.toUTF8String(result);
7239596a2c1Sopenharmony_ci    return PseudoLocalizationProcessor(GetDisplayNameByTaboo(localeStr, result));
7249596a2c1Sopenharmony_ci}
7259596a2c1Sopenharmony_ci
7269596a2c1Sopenharmony_cistd::string I18nTimeZone::GetDisplayNameByTaboo(
7279596a2c1Sopenharmony_ci    const std::string& localeStr, std::string result)
7289596a2c1Sopenharmony_ci{
7299596a2c1Sopenharmony_ci    void *i18nUtilHandle = dlopen("libi18n_util.z.so", RTLD_NOW);
7309596a2c1Sopenharmony_ci    if (i18nUtilHandle == nullptr) {
7319596a2c1Sopenharmony_ci        return result;
7329596a2c1Sopenharmony_ci    }
7339596a2c1Sopenharmony_ci    GetReplacedTimezoneDisplayName getReplacedTimezoneDisplayName =
7349596a2c1Sopenharmony_ci        (GetReplacedTimezoneDisplayName)dlsym(i18nUtilHandle, "GetReplacedTimezoneDisplayName");
7359596a2c1Sopenharmony_ci
7369596a2c1Sopenharmony_ci    char recvArr[RECV_CHAR_LEN];
7379596a2c1Sopenharmony_ci    int err = strcpy_s(recvArr, RECV_CHAR_LEN, result.c_str());
7389596a2c1Sopenharmony_ci    if (err != 0) {
7399596a2c1Sopenharmony_ci        return result;
7409596a2c1Sopenharmony_ci    }
7419596a2c1Sopenharmony_ci    if (getReplacedTimezoneDisplayName) {
7429596a2c1Sopenharmony_ci        getReplacedTimezoneDisplayName(localeStr.c_str(), GetID().c_str(), recvArr);
7439596a2c1Sopenharmony_ci    }
7449596a2c1Sopenharmony_ci    result = recvArr;
7459596a2c1Sopenharmony_ci    dlclose(i18nUtilHandle);
7469596a2c1Sopenharmony_ci    return result;
7479596a2c1Sopenharmony_ci}
7489596a2c1Sopenharmony_ci
7499596a2c1Sopenharmony_cibool I18nTimeZone::ReadTimeZoneData(const char *xmlPath)
7509596a2c1Sopenharmony_ci{
7519596a2c1Sopenharmony_ci    xmlKeepBlanksDefault(0);
7529596a2c1Sopenharmony_ci    if (xmlPath == nullptr) {
7539596a2c1Sopenharmony_ci        return false;
7549596a2c1Sopenharmony_ci    }
7559596a2c1Sopenharmony_ci    xmlDocPtr doc = xmlParseFile(xmlPath);
7569596a2c1Sopenharmony_ci    if (!doc) {
7579596a2c1Sopenharmony_ci        return false;
7589596a2c1Sopenharmony_ci    }
7599596a2c1Sopenharmony_ci    xmlNodePtr cur = xmlDocGetRootElement(doc);
7609596a2c1Sopenharmony_ci    if (!cur || xmlStrcmp(cur->name, reinterpret_cast<const xmlChar *>(TIMEZONE_ROOT_TAG))) {
7619596a2c1Sopenharmony_ci        xmlFreeDoc(doc);
7629596a2c1Sopenharmony_ci        return false;
7639596a2c1Sopenharmony_ci    }
7649596a2c1Sopenharmony_ci    cur = cur->xmlChildrenNode;
7659596a2c1Sopenharmony_ci    while (cur != nullptr && !xmlStrcmp(cur->name, reinterpret_cast<const xmlChar *>(TIMEZONE_SECOND_ROOT_TAG))) {
7669596a2c1Sopenharmony_ci        xmlNodePtr value = cur->xmlChildrenNode;
7679596a2c1Sopenharmony_ci        xmlChar *contents[ELEMENT_NUM] = { 0 }; // 2 represent cityid, zoneid;
7689596a2c1Sopenharmony_ci        bool xmlNodeIsNull = false;
7699596a2c1Sopenharmony_ci        for (size_t i = 0; i < ELEMENT_NUM && value != nullptr; i++) {
7709596a2c1Sopenharmony_ci            contents[i] = xmlNodeGetContent(value);
7719596a2c1Sopenharmony_ci            value = value->next;
7729596a2c1Sopenharmony_ci            if (contents[i] == nullptr) {
7739596a2c1Sopenharmony_ci                xmlNodeIsNull = true;
7749596a2c1Sopenharmony_ci            }
7759596a2c1Sopenharmony_ci        }
7769596a2c1Sopenharmony_ci        if (!xmlNodeIsNull) {
7779596a2c1Sopenharmony_ci            // 0 represents cityid index, 1 represents zoneid index
7789596a2c1Sopenharmony_ci            availableZoneCityIDs.insert(reinterpret_cast<const char *>(contents[0]));
7799596a2c1Sopenharmony_ci            const char* pairKey = reinterpret_cast<const char *>(contents[0]);
7809596a2c1Sopenharmony_ci            const char* pairVal = reinterpret_cast<const char *>(contents[1]);
7819596a2c1Sopenharmony_ci            SetCity2TimeZoneID(pairKey, pairVal);
7829596a2c1Sopenharmony_ci        }
7839596a2c1Sopenharmony_ci        for (size_t i = 0; i < ELEMENT_NUM; i++) {
7849596a2c1Sopenharmony_ci            if (contents[i] != nullptr) {
7859596a2c1Sopenharmony_ci                xmlFree(contents[i]);
7869596a2c1Sopenharmony_ci            }
7879596a2c1Sopenharmony_ci        }
7889596a2c1Sopenharmony_ci        cur = cur->next;
7899596a2c1Sopenharmony_ci    }
7909596a2c1Sopenharmony_ci    xmlFreeDoc(doc);
7919596a2c1Sopenharmony_ci    return true;
7929596a2c1Sopenharmony_ci}
7939596a2c1Sopenharmony_ci
7949596a2c1Sopenharmony_civoid I18nTimeZone::SetCity2TimeZoneID(const char* key, const char* value)
7959596a2c1Sopenharmony_ci{
7969596a2c1Sopenharmony_ci    std::lock_guard<std::mutex> cityTzLock(cityTimeZoneMutex);
7979596a2c1Sopenharmony_ci    city2TimeZoneID.insert(
7989596a2c1Sopenharmony_ci        std::make_pair<std::string, std::string>(key, value));
7999596a2c1Sopenharmony_ci}
8009596a2c1Sopenharmony_ci
8019596a2c1Sopenharmony_civoid I18nTimeZone::GetTimezoneIDFromZoneInfo(std::set<std::string> &availableIDs, std::string &parentPath,
8029596a2c1Sopenharmony_ci    std::string &parentName)
8039596a2c1Sopenharmony_ci{
8049596a2c1Sopenharmony_ci    using std::filesystem::directory_iterator;
8059596a2c1Sopenharmony_ci
8069596a2c1Sopenharmony_ci    struct stat s;
8079596a2c1Sopenharmony_ci    for (const auto &dirEntry : directory_iterator{parentPath}) {
8089596a2c1Sopenharmony_ci        std::string zonePath = dirEntry.path();
8099596a2c1Sopenharmony_ci        if (stat(zonePath.c_str(), &s) != 0) {
8109596a2c1Sopenharmony_ci            HILOG_ERROR_I18N("GetTimezoneIDFromZoneInfo: zoneinfo path %{public}s not exist.", parentPath.c_str());
8119596a2c1Sopenharmony_ci            return;
8129596a2c1Sopenharmony_ci        }
8139596a2c1Sopenharmony_ci        std::string zoneName = zonePath.substr(parentPath.length() + 1); // 1 add length of path splitor
8149596a2c1Sopenharmony_ci        std::string finalZoneName = parentName + "/" + zoneName;
8159596a2c1Sopenharmony_ci        if (s.st_mode & S_IFDIR) {
8169596a2c1Sopenharmony_ci            GetTimezoneIDFromZoneInfo(availableIDs, zonePath, finalZoneName);
8179596a2c1Sopenharmony_ci        } else {
8189596a2c1Sopenharmony_ci            availableIDs.insert(finalZoneName);
8199596a2c1Sopenharmony_ci        }
8209596a2c1Sopenharmony_ci    }
8219596a2c1Sopenharmony_ci}
8229596a2c1Sopenharmony_ci
8239596a2c1Sopenharmony_cistd::set<std::string> I18nTimeZone::GetAvailableIDs(I18nErrorCode &errorCode)
8249596a2c1Sopenharmony_ci{
8259596a2c1Sopenharmony_ci    return GetTimeZoneAvailableIDs(errorCode);
8269596a2c1Sopenharmony_ci}
8279596a2c1Sopenharmony_ci
8289596a2c1Sopenharmony_cistd::set<std::string> I18nTimeZone::GetAvailableZoneCityIDs()
8299596a2c1Sopenharmony_ci{
8309596a2c1Sopenharmony_ci    if (availableZoneCityIDs.size() != 0) {
8319596a2c1Sopenharmony_ci        return availableZoneCityIDs;
8329596a2c1Sopenharmony_ci    }
8339596a2c1Sopenharmony_ci    struct stat s;
8349596a2c1Sopenharmony_ci    if (stat(DISTRO_DEVICE_CITY_TIMEZONE_DATA_PATH, &s) == 0) {
8359596a2c1Sopenharmony_ci        ReadTimeZoneData(DISTRO_DEVICE_CITY_TIMEZONE_DATA_PATH);
8369596a2c1Sopenharmony_ci    } else if (stat(DEVICE_CITY_TIMEZONE_DATA_PATH, &s) == 0) {
8379596a2c1Sopenharmony_ci        ReadTimeZoneData(DEVICE_CITY_TIMEZONE_DATA_PATH);
8389596a2c1Sopenharmony_ci    } else {
8399596a2c1Sopenharmony_ci        ReadTimeZoneData(CITY_TIMEZONE_DATA_PATH);
8409596a2c1Sopenharmony_ci    }
8419596a2c1Sopenharmony_ci    return availableZoneCityIDs;
8429596a2c1Sopenharmony_ci}
8439596a2c1Sopenharmony_ci
8449596a2c1Sopenharmony_cistd::string I18nTimeZone::FindCityDisplayNameFromXml(std::string &cityID, std::string &locale)
8459596a2c1Sopenharmony_ci{
8469596a2c1Sopenharmony_ci    xmlKeepBlanksDefault(0);
8479596a2c1Sopenharmony_ci    std::string xmlPath = GetCityDisplayNameXmlPath(locale);
8489596a2c1Sopenharmony_ci    xmlDocPtr doc = xmlParseFile(xmlPath.c_str());
8499596a2c1Sopenharmony_ci    if (!doc) {
8509596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("FindCityDisplayNameFromXml: can't parse city displayname: %{public}s", xmlPath.c_str());
8519596a2c1Sopenharmony_ci        return "";
8529596a2c1Sopenharmony_ci    }
8539596a2c1Sopenharmony_ci    xmlNodePtr cur = xmlDocGetRootElement(doc);
8549596a2c1Sopenharmony_ci    if (!cur || xmlStrcmp(cur->name, reinterpret_cast<const xmlChar *>(CITY_DISPLAYNAME_ROOT_TAG))) {
8559596a2c1Sopenharmony_ci        xmlFreeDoc(doc);
8569596a2c1Sopenharmony_ci        HILOG_ERROR_I18N(
8579596a2c1Sopenharmony_ci            "FindCityDisplayNameFromXml: city displayname file %{public}s has wrong root tag.", xmlPath.c_str());
8589596a2c1Sopenharmony_ci        return "";
8599596a2c1Sopenharmony_ci    }
8609596a2c1Sopenharmony_ci    cur = cur->xmlChildrenNode;
8619596a2c1Sopenharmony_ci    std::string displayName;
8629596a2c1Sopenharmony_ci    while (cur != nullptr && !xmlStrcmp(cur->name,
8639596a2c1Sopenharmony_ci        reinterpret_cast<const xmlChar *>(CITY_DISPLAYNAME_SECOND_ROOT_TAG))) {
8649596a2c1Sopenharmony_ci        xmlNodePtr value = cur->xmlChildrenNode;
8659596a2c1Sopenharmony_ci        xmlChar *contents[ELEMENT_NUM] = { 0 }; // 2 represent cityid, displayName;
8669596a2c1Sopenharmony_ci        bool xmlNodeIsNull = false;
8679596a2c1Sopenharmony_ci        for (size_t i = 0; i < ELEMENT_NUM; i++) {
8689596a2c1Sopenharmony_ci            if (value == nullptr) {
8699596a2c1Sopenharmony_ci                xmlNodeIsNull = true;
8709596a2c1Sopenharmony_ci                break;
8719596a2c1Sopenharmony_ci            }
8729596a2c1Sopenharmony_ci            contents[i] = xmlNodeGetContent(value);
8739596a2c1Sopenharmony_ci            if (contents[i] == nullptr) {
8749596a2c1Sopenharmony_ci                xmlNodeIsNull = true;
8759596a2c1Sopenharmony_ci                break;
8769596a2c1Sopenharmony_ci            }
8779596a2c1Sopenharmony_ci            value = value->next;
8789596a2c1Sopenharmony_ci        }
8799596a2c1Sopenharmony_ci        if (!xmlNodeIsNull && strcmp(cityID.c_str(), reinterpret_cast<const char *>(contents[0])) == 0) {
8809596a2c1Sopenharmony_ci            displayName = reinterpret_cast<const char *>(contents[1]);
8819596a2c1Sopenharmony_ci        }
8829596a2c1Sopenharmony_ci        for (size_t i = 0; i < ELEMENT_NUM; i++) {
8839596a2c1Sopenharmony_ci            if (contents[i] != nullptr) {
8849596a2c1Sopenharmony_ci                xmlFree(contents[i]);
8859596a2c1Sopenharmony_ci            }
8869596a2c1Sopenharmony_ci        }
8879596a2c1Sopenharmony_ci        if (displayName.length() != 0) {
8889596a2c1Sopenharmony_ci            break;
8899596a2c1Sopenharmony_ci        }
8909596a2c1Sopenharmony_ci        cur = cur->next;
8919596a2c1Sopenharmony_ci    }
8929596a2c1Sopenharmony_ci    xmlFreeDoc(doc);
8939596a2c1Sopenharmony_ci    return displayName;
8949596a2c1Sopenharmony_ci}
8959596a2c1Sopenharmony_ci
8969596a2c1Sopenharmony_cistd::string I18nTimeZone::GetCityDisplayNameXmlPath(const std::string &locale)
8979596a2c1Sopenharmony_ci{
8989596a2c1Sopenharmony_ci    const char *deviceCityDisplayNamePath = GetDeviceCityDisplayNamePath();
8999596a2c1Sopenharmony_ci    if (strlen(deviceCityDisplayNamePath) != 0) {
9009596a2c1Sopenharmony_ci        return deviceCityDisplayNamePath + locale + ".xml";
9019596a2c1Sopenharmony_ci    } else {
9029596a2c1Sopenharmony_ci        return CITY_DISPLAYNAME_PATH + locale + ".xml";
9039596a2c1Sopenharmony_ci    }
9049596a2c1Sopenharmony_ci}
9059596a2c1Sopenharmony_ci
9069596a2c1Sopenharmony_cistd::map<std::string, std::string> I18nTimeZone::FindCityDisplayNameMap(std::string &locale)
9079596a2c1Sopenharmony_ci{
9089596a2c1Sopenharmony_ci    xmlKeepBlanksDefault(0);
9099596a2c1Sopenharmony_ci    std::map<std::string, std::string> resultMap;
9109596a2c1Sopenharmony_ci    std::string xmlPath = GetCityDisplayNameXmlPath(locale);
9119596a2c1Sopenharmony_ci    xmlDocPtr doc = xmlParseFile(xmlPath.c_str());
9129596a2c1Sopenharmony_ci    if (!doc) {
9139596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("FindCityDisplayNameMap: can't parse city displayname file %{public}s", xmlPath.c_str());
9149596a2c1Sopenharmony_ci        return resultMap;
9159596a2c1Sopenharmony_ci    }
9169596a2c1Sopenharmony_ci    xmlNodePtr cur = xmlDocGetRootElement(doc);
9179596a2c1Sopenharmony_ci    if (!cur || xmlStrcmp(cur->name, reinterpret_cast<const xmlChar *>(CITY_DISPLAYNAME_ROOT_TAG))) {
9189596a2c1Sopenharmony_ci        xmlFreeDoc(doc);
9199596a2c1Sopenharmony_ci        HILOG_ERROR_I18N(
9209596a2c1Sopenharmony_ci            "FindCityDisplayNameMap: city displayname file %{public}s has wrong root tag.", xmlPath.c_str());
9219596a2c1Sopenharmony_ci        return resultMap;
9229596a2c1Sopenharmony_ci    }
9239596a2c1Sopenharmony_ci    cur = cur->xmlChildrenNode;
9249596a2c1Sopenharmony_ci    while (cur != nullptr && !xmlStrcmp(cur->name,
9259596a2c1Sopenharmony_ci        reinterpret_cast<const xmlChar *>(CITY_DISPLAYNAME_SECOND_ROOT_TAG))) {
9269596a2c1Sopenharmony_ci        xmlNodePtr value = cur->xmlChildrenNode;
9279596a2c1Sopenharmony_ci        xmlChar *contents[ELEMENT_NUM] = { 0 }; // 2 represent cityid, displayName;
9289596a2c1Sopenharmony_ci        bool xmlNodeIsNull = false;
9299596a2c1Sopenharmony_ci        for (size_t i = 0; i < ELEMENT_NUM && value != nullptr; i++) {
9309596a2c1Sopenharmony_ci            contents[i] = xmlNodeGetContent(value);
9319596a2c1Sopenharmony_ci            value = value->next;
9329596a2c1Sopenharmony_ci            if (contents[i] == nullptr) {
9339596a2c1Sopenharmony_ci                xmlNodeIsNull = true;
9349596a2c1Sopenharmony_ci            }
9359596a2c1Sopenharmony_ci        }
9369596a2c1Sopenharmony_ci        if (!xmlNodeIsNull) {
9379596a2c1Sopenharmony_ci            const char* key = reinterpret_cast<const char *>(contents[0]);
9389596a2c1Sopenharmony_ci            const char* displayName = reinterpret_cast<const char *>(contents[1]);
9399596a2c1Sopenharmony_ci            resultMap.insert(std::make_pair<std::string, std::string>(key, displayName));
9409596a2c1Sopenharmony_ci        }
9419596a2c1Sopenharmony_ci        for (size_t i = 0; i < ELEMENT_NUM; i++) {
9429596a2c1Sopenharmony_ci            if (contents[i] != nullptr) {
9439596a2c1Sopenharmony_ci                xmlFree(contents[i]);
9449596a2c1Sopenharmony_ci            }
9459596a2c1Sopenharmony_ci        }
9469596a2c1Sopenharmony_ci        cur = cur->next;
9479596a2c1Sopenharmony_ci    }
9489596a2c1Sopenharmony_ci    xmlFreeDoc(doc);
9499596a2c1Sopenharmony_ci    return resultMap;
9509596a2c1Sopenharmony_ci}
9519596a2c1Sopenharmony_ci
9529596a2c1Sopenharmony_cibool I18nTimeZone::GetSupportedLocales()
9539596a2c1Sopenharmony_ci{
9549596a2c1Sopenharmony_ci    using std::filesystem::directory_iterator;
9559596a2c1Sopenharmony_ci
9569596a2c1Sopenharmony_ci    struct stat s;
9579596a2c1Sopenharmony_ci    std::string displayNamePath = GetDeviceCityDisplayNamePath();
9589596a2c1Sopenharmony_ci    if (displayNamePath.length() == 0) {
9599596a2c1Sopenharmony_ci        displayNamePath = CITY_DISPLAYNAME_PATH;
9609596a2c1Sopenharmony_ci    }
9619596a2c1Sopenharmony_ci    for (const auto &dirEntry : directory_iterator{displayNamePath}) {
9629596a2c1Sopenharmony_ci        std::string xmlPath = dirEntry.path();
9639596a2c1Sopenharmony_ci        if (stat(xmlPath.c_str(), &s) != 0) {
9649596a2c1Sopenharmony_ci            HILOG_ERROR_I18N("city displayname file %{public}s not exist.", xmlPath.c_str());
9659596a2c1Sopenharmony_ci            return false;
9669596a2c1Sopenharmony_ci        }
9679596a2c1Sopenharmony_ci        int32_t localeStrLen = static_cast<int32_t>(xmlPath.length()) - static_cast<int32_t>(
9689596a2c1Sopenharmony_ci            displayNamePath.length()) - 4;  // 4 is the length of ".xml"
9699596a2c1Sopenharmony_ci        std::string localeStr = xmlPath.substr(displayNamePath.length(), localeStrLen);
9709596a2c1Sopenharmony_ci        supportedLocales.insert(localeStr);
9719596a2c1Sopenharmony_ci    }
9729596a2c1Sopenharmony_ci    return true;
9739596a2c1Sopenharmony_ci}
9749596a2c1Sopenharmony_ci
9759596a2c1Sopenharmony_cistd::string I18nTimeZone::GetFallBack(std::string &requestLocaleStr)
9769596a2c1Sopenharmony_ci{
9779596a2c1Sopenharmony_ci    auto iter = BEST_MATCH_LOCALE.find(requestLocaleStr);
9789596a2c1Sopenharmony_ci    if (iter != BEST_MATCH_LOCALE.end()) {
9799596a2c1Sopenharmony_ci        return iter->second;
9809596a2c1Sopenharmony_ci    }
9819596a2c1Sopenharmony_ci    std::vector<LocaleInfo*> matchLocaleList;
9829596a2c1Sopenharmony_ci    std::unique_ptr<LocaleInfo> requestLocale = std::make_unique<LocaleInfo>(requestLocaleStr);
9839596a2c1Sopenharmony_ci    for (auto it = supportedLocales.begin(); it != supportedLocales.end(); ++it) {
9849596a2c1Sopenharmony_ci        std::string tempLocaleStr = it->data();
9859596a2c1Sopenharmony_ci        tempLocaleStr = StrReplaceAll(tempLocaleStr, "_", "-");
9869596a2c1Sopenharmony_ci        LocaleInfo* tempLocale = new LocaleInfo(tempLocaleStr);
9879596a2c1Sopenharmony_ci        if (LocaleMatcher::Match(requestLocale.get(), tempLocale)) {
9889596a2c1Sopenharmony_ci            matchLocaleList.push_back(tempLocale);
9899596a2c1Sopenharmony_ci        } else {
9909596a2c1Sopenharmony_ci            delete tempLocale;
9919596a2c1Sopenharmony_ci        }
9929596a2c1Sopenharmony_ci    }
9939596a2c1Sopenharmony_ci    std::string bestMatchLocaleTag = DEFAULT_LOCALE;
9949596a2c1Sopenharmony_ci    if (matchLocaleList.size() == 0) {
9959596a2c1Sopenharmony_ci        return bestMatchLocaleTag;
9969596a2c1Sopenharmony_ci    }
9979596a2c1Sopenharmony_ci    LocaleInfo *bestMatch = matchLocaleList[0];
9989596a2c1Sopenharmony_ci    for (size_t i = 1; i < matchLocaleList.size(); ++i) {
9999596a2c1Sopenharmony_ci        if (LocaleMatcher::IsMoreSuitable(bestMatch, matchLocaleList[i], requestLocale.get()) < 0) {
10009596a2c1Sopenharmony_ci            bestMatch = matchLocaleList[i];
10019596a2c1Sopenharmony_ci        }
10029596a2c1Sopenharmony_ci    }
10039596a2c1Sopenharmony_ci    bestMatchLocaleTag = bestMatch->ToString();
10049596a2c1Sopenharmony_ci    for (size_t i = 0; i < matchLocaleList.size(); ++i) {
10059596a2c1Sopenharmony_ci        delete matchLocaleList[i];
10069596a2c1Sopenharmony_ci    }
10079596a2c1Sopenharmony_ci    bestMatchLocaleTag = StrReplaceAll(bestMatchLocaleTag, "-", "_");
10089596a2c1Sopenharmony_ci    SetBestMatchLocale(requestLocaleStr, bestMatchLocaleTag);
10099596a2c1Sopenharmony_ci    return bestMatchLocaleTag;
10109596a2c1Sopenharmony_ci}
10119596a2c1Sopenharmony_ci
10129596a2c1Sopenharmony_civoid I18nTimeZone::SetBestMatchLocale(const std::string& key, const std::string& value)
10139596a2c1Sopenharmony_ci{
10149596a2c1Sopenharmony_ci    std::lock_guard<std::mutex> matchLocaleLock(matchLocaleMutex);
10159596a2c1Sopenharmony_ci    BEST_MATCH_LOCALE.insert(std::make_pair(key, value));
10169596a2c1Sopenharmony_ci}
10179596a2c1Sopenharmony_ci
10189596a2c1Sopenharmony_cistd::string I18nTimeZone::GetCityDisplayName(std::string &cityID, std::string &localeStr)
10199596a2c1Sopenharmony_ci{
10209596a2c1Sopenharmony_ci    if (availableZoneCityIDs.size() == 0) {
10219596a2c1Sopenharmony_ci        GetAvailableZoneCityIDs();
10229596a2c1Sopenharmony_ci    }
10239596a2c1Sopenharmony_ci    if (availableZoneCityIDs.find(cityID) == availableZoneCityIDs.end()) {
10249596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("%{public}s is not supported cityID.", cityID.c_str());
10259596a2c1Sopenharmony_ci        return PseudoLocalizationProcessor("");
10269596a2c1Sopenharmony_ci    }
10279596a2c1Sopenharmony_ci    std::string requestLocaleStr = GetLocaleBaseName(localeStr);
10289596a2c1Sopenharmony_ci    if (requestLocaleStr.length() != 0) {
10299596a2c1Sopenharmony_ci        std::string displayName = FindCityDisplayNameFromXml(cityID, requestLocaleStr);
10309596a2c1Sopenharmony_ci        if (displayName.length() != 0) {
10319596a2c1Sopenharmony_ci            return PseudoLocalizationProcessor(displayName);
10329596a2c1Sopenharmony_ci        }
10339596a2c1Sopenharmony_ci    }
10349596a2c1Sopenharmony_ci    return PseudoLocalizationProcessor("");
10359596a2c1Sopenharmony_ci}
10369596a2c1Sopenharmony_ci
10379596a2c1Sopenharmony_cistd::string I18nTimeZone::GetLocaleBaseName(std::string &localeStr)
10389596a2c1Sopenharmony_ci{
10399596a2c1Sopenharmony_ci    if (supportedLocales.size() == 0) {
10409596a2c1Sopenharmony_ci        bool status = GetSupportedLocales();
10419596a2c1Sopenharmony_ci        if (!status) {
10429596a2c1Sopenharmony_ci            HILOG_ERROR_I18N("get supported Locales failed");
10439596a2c1Sopenharmony_ci            return "";
10449596a2c1Sopenharmony_ci        }
10459596a2c1Sopenharmony_ci    }
10469596a2c1Sopenharmony_ci    UErrorCode errorCode = U_ZERO_ERROR;
10479596a2c1Sopenharmony_ci    icu::Locale locale = icu::Locale::forLanguageTag(localeStr, errorCode);
10489596a2c1Sopenharmony_ci    if (U_FAILURE(errorCode)) {
10499596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("create icu Locale for %{public}s failed", localeStr.c_str());
10509596a2c1Sopenharmony_ci        return "";
10519596a2c1Sopenharmony_ci    }
10529596a2c1Sopenharmony_ci    std::string requestLocaleStr = locale.getBaseName();
10539596a2c1Sopenharmony_ci    requestLocaleStr = StrReplaceAll(requestLocaleStr, "_", "-");
10549596a2c1Sopenharmony_ci    return GetFallBack(requestLocaleStr);
10559596a2c1Sopenharmony_ci}
10569596a2c1Sopenharmony_ci
10579596a2c1Sopenharmony_cistd::string I18nTimeZone::GetTimezoneIdByCityId(const std::string &cityId)
10589596a2c1Sopenharmony_ci{
10599596a2c1Sopenharmony_ci    if (city2TimeZoneID.size() == 0) {
10609596a2c1Sopenharmony_ci        GetAvailableZoneCityIDs();
10619596a2c1Sopenharmony_ci    }
10629596a2c1Sopenharmony_ci    if (city2TimeZoneID.find(cityId) == city2TimeZoneID.end()) {
10639596a2c1Sopenharmony_ci        return "";
10649596a2c1Sopenharmony_ci    } else {
10659596a2c1Sopenharmony_ci        return city2TimeZoneID.at(cityId);
10669596a2c1Sopenharmony_ci    }
10679596a2c1Sopenharmony_ci}
10689596a2c1Sopenharmony_ci
10699596a2c1Sopenharmony_cistd::vector<std::string> I18nTimeZone::GetTimezoneIdByLocation(const double x, const double y)
10709596a2c1Sopenharmony_ci{
10719596a2c1Sopenharmony_ci    std::vector<std::string> tzIdList;
10729596a2c1Sopenharmony_ci#ifdef SUPPORT_GRAPHICS
10739596a2c1Sopenharmony_ci    if (!CheckLatitudeAndLongitude(x, y)) {
10749596a2c1Sopenharmony_ci        return tzIdList;
10759596a2c1Sopenharmony_ci    }
10769596a2c1Sopenharmony_ci    std::map<int, std::string> categoryMap = GetTimeZoneCategoryMap(x, y);
10779596a2c1Sopenharmony_ci    std::vector<std::string> filePaths = FindTzData();
10789596a2c1Sopenharmony_ci    size_t fileCount = filePaths.size();
10799596a2c1Sopenharmony_ci    if (fileCount < 1) {
10809596a2c1Sopenharmony_ci        return tzIdList;
10819596a2c1Sopenharmony_ci    }
10829596a2c1Sopenharmony_ci    std::string preferredPath = GetPreferredPath(x, filePaths);
10839596a2c1Sopenharmony_ci    if (preferredPath == "") {
10849596a2c1Sopenharmony_ci        return tzIdList;
10859596a2c1Sopenharmony_ci    }
10869596a2c1Sopenharmony_ci    uint32_t width = 0;
10879596a2c1Sopenharmony_ci    uint32_t height = 0;
10889596a2c1Sopenharmony_ci    GetTzDataWidth(filePaths, &width, &height);
10899596a2c1Sopenharmony_ci    double calculateX = y * width / (TZ_X_PLUS * 1.0) + width / (TZ_HALF_OF_SIZE * 1.0);
10909596a2c1Sopenharmony_ci    double calculateY = x * ((height * fileCount) / (TZ_X_PLUS * TZ_HALF_OF_SIZE * 1.0)) +
10919596a2c1Sopenharmony_ci                        (height * fileCount) / (TZ_HALF_OF_SIZE * 1.0);
10929596a2c1Sopenharmony_ci    uint16_t fixedX = static_cast<uint16_t>(calculateX);
10939596a2c1Sopenharmony_ci    uint16_t fixedY = static_cast<uint16_t>(calculateY);
10949596a2c1Sopenharmony_ci    if (ParamExceedScope(fixedX, fixedY, width, height * fileCount)) {
10959596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("invalid width:%{public}d or height: %{public}d", fixedX, fixedY);
10969596a2c1Sopenharmony_ci        return tzIdList;
10979596a2c1Sopenharmony_ci    }
10989596a2c1Sopenharmony_ci    uint16_t actualHeight = fileCount > 1 ? (fixedY % height) : fixedY;
10999596a2c1Sopenharmony_ci    std::vector<int> pixel = GetColorData(fixedX, fixedY, actualHeight, preferredPath);
11009596a2c1Sopenharmony_ci    for (size_t i = 0; i < pixel.size(); i++) {
11019596a2c1Sopenharmony_ci        //255 is invalid pixel value required
11029596a2c1Sopenharmony_ci        if (pixel[i] != TZ_MAX_PIXEL_VALUE && categoryMap.find(pixel[i]) != categoryMap.end()) {
11039596a2c1Sopenharmony_ci            std::string zdId = categoryMap[pixel[i]];
11049596a2c1Sopenharmony_ci            tzIdList.push_back(zdId);
11059596a2c1Sopenharmony_ci        }
11069596a2c1Sopenharmony_ci    }
11079596a2c1Sopenharmony_ci#endif
11089596a2c1Sopenharmony_ci    return tzIdList;
11099596a2c1Sopenharmony_ci}
11109596a2c1Sopenharmony_ci
11119596a2c1Sopenharmony_cistd::map<int, std::string> I18nTimeZone::GetTimeZoneCategoryMap(const double x, const double y)
11129596a2c1Sopenharmony_ci{
11139596a2c1Sopenharmony_ci    if (x < 0 && y >= 0) {
11149596a2c1Sopenharmony_ci        return categoryNum2TimezoneWN;
11159596a2c1Sopenharmony_ci    } else if (x >= 0 && y >= 0) {
11169596a2c1Sopenharmony_ci        return categoryNum2TimezoneEN;
11179596a2c1Sopenharmony_ci    } else if (x < 0 && y < 0) {
11189596a2c1Sopenharmony_ci        return categoryNum2TimezoneWS;
11199596a2c1Sopenharmony_ci    } else {
11209596a2c1Sopenharmony_ci        return categoryNum2TimezoneES;
11219596a2c1Sopenharmony_ci    }
11229596a2c1Sopenharmony_ci}
11239596a2c1Sopenharmony_ci
11249596a2c1Sopenharmony_cibool I18nTimeZone::CheckLatitudeAndLongitude(const double x, const double y)
11259596a2c1Sopenharmony_ci{
11269596a2c1Sopenharmony_ci    if (x < -1.0 * TZ_X_PLUS) {
11279596a2c1Sopenharmony_ci        return false;
11289596a2c1Sopenharmony_ci    }
11299596a2c1Sopenharmony_ci    if (x >= TZ_X_PLUS * 1.0 - NUM_PRECISION) {
11309596a2c1Sopenharmony_ci        return false;
11319596a2c1Sopenharmony_ci    }
11329596a2c1Sopenharmony_ci    if (y < -1.0 * TZ_X_PLUS/TZ_HALF_OF_SIZE) {
11339596a2c1Sopenharmony_ci        return false;
11349596a2c1Sopenharmony_ci    }
11359596a2c1Sopenharmony_ci    if (y >= TZ_X_PLUS * 1.0/TZ_HALF_OF_SIZE - NUM_PRECISION) {
11369596a2c1Sopenharmony_ci        return false;
11379596a2c1Sopenharmony_ci    }
11389596a2c1Sopenharmony_ci    return true;
11399596a2c1Sopenharmony_ci}
11409596a2c1Sopenharmony_ci
11419596a2c1Sopenharmony_cistd::vector<int> I18nTimeZone::GetColorData(const uint16_t x, const uint16_t y,
11429596a2c1Sopenharmony_ci                                            uint16_t actualHeight, std::string preferredPath)
11439596a2c1Sopenharmony_ci{
11449596a2c1Sopenharmony_ci    std::vector<int> result;
11459596a2c1Sopenharmony_ci    FILE *fp;
11469596a2c1Sopenharmony_ci    png_structp png_ptr;
11479596a2c1Sopenharmony_ci    png_infop info_ptr;
11489596a2c1Sopenharmony_ci    png_bytep row_pointers;
11499596a2c1Sopenharmony_ci    int code = InitPngptr(png_ptr, info_ptr, &fp, preferredPath);
11509596a2c1Sopenharmony_ci    if (code != 0) {
11519596a2c1Sopenharmony_ci        return result;
11529596a2c1Sopenharmony_ci    }
11539596a2c1Sopenharmony_ci    try {
11549596a2c1Sopenharmony_ci        rewind(fp);
11559596a2c1Sopenharmony_ci        png_init_io(png_ptr, fp);
11569596a2c1Sopenharmony_ci        png_read_info(png_ptr, info_ptr);
11579596a2c1Sopenharmony_ci        unsigned int rowbytes = png_get_rowbytes(png_ptr, info_ptr);
11589596a2c1Sopenharmony_ci        row_pointers = (png_bytep)png_malloc(png_ptr, rowbytes);
11599596a2c1Sopenharmony_ci        if (row_pointers == nullptr) {
11609596a2c1Sopenharmony_ci            png_destroy_read_struct(&png_ptr, &info_ptr, 0);
11619596a2c1Sopenharmony_ci            CloseFile(fp);
11629596a2c1Sopenharmony_ci            HILOG_ERROR_I18N("malloc rowbytes failed.");
11639596a2c1Sopenharmony_ci            return result;
11649596a2c1Sopenharmony_ci        }
11659596a2c1Sopenharmony_ci        png_start_read_image(png_ptr);
11669596a2c1Sopenharmony_ci        for (int i = 0; i < (actualHeight + 1); i++) {
11679596a2c1Sopenharmony_ci            png_read_row(png_ptr, row_pointers, NULL);
11689596a2c1Sopenharmony_ci        }
11699596a2c1Sopenharmony_ci        for (size_t i = 0; i < 3; i++) { // 3 is RGB color pixel length
11709596a2c1Sopenharmony_ci            std::string pixel = std::to_string(*(row_pointers + x * 3 + i)); // 3 is RGB color pixel length
11719596a2c1Sopenharmony_ci            result.push_back(atoi(pixel.c_str()));
11729596a2c1Sopenharmony_ci        }
11739596a2c1Sopenharmony_ci        png_free(png_ptr, row_pointers);
11749596a2c1Sopenharmony_ci        CloseFile(fp);
11759596a2c1Sopenharmony_ci    } catch (...) {
11769596a2c1Sopenharmony_ci        png_destroy_read_struct(&png_ptr, &info_ptr, 0);
11779596a2c1Sopenharmony_ci        CloseFile(fp);
11789596a2c1Sopenharmony_ci    }
11799596a2c1Sopenharmony_ci    return result;
11809596a2c1Sopenharmony_ci}
11819596a2c1Sopenharmony_ci
11829596a2c1Sopenharmony_civoid I18nTimeZone::GetTzDataWidth(std::vector<std::string> filePaths, uint32_t *width, uint32_t *height)
11839596a2c1Sopenharmony_ci{
11849596a2c1Sopenharmony_ci    if (filePaths.size() == 0 || !CheckTzDataFilePath(filePaths.at(0))) {
11859596a2c1Sopenharmony_ci        return;
11869596a2c1Sopenharmony_ci    } else {
11879596a2c1Sopenharmony_ci        FILE* fp;
11889596a2c1Sopenharmony_ci        png_structp png_ptr;
11899596a2c1Sopenharmony_ci        png_infop info_ptr;
11909596a2c1Sopenharmony_ci        try {
11919596a2c1Sopenharmony_ci            std::string path = filePaths.at(0);
11929596a2c1Sopenharmony_ci            fp = fopen(path.c_str(), "rb");
11939596a2c1Sopenharmony_ci            if (fp == NULL) {
11949596a2c1Sopenharmony_ci                return;
11959596a2c1Sopenharmony_ci            }
11969596a2c1Sopenharmony_ci            png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
11979596a2c1Sopenharmony_ci            info_ptr = png_create_info_struct(png_ptr);
11989596a2c1Sopenharmony_ci            rewind(fp);
11999596a2c1Sopenharmony_ci            png_init_io(png_ptr, fp);
12009596a2c1Sopenharmony_ci            png_read_info(png_ptr, info_ptr);
12019596a2c1Sopenharmony_ci            unsigned int w, h;
12029596a2c1Sopenharmony_ci            png_get_IHDR(png_ptr, info_ptr, &w, &h, NULL, NULL, NULL, NULL, NULL);
12039596a2c1Sopenharmony_ci            *width = w;
12049596a2c1Sopenharmony_ci            *height = h;
12059596a2c1Sopenharmony_ci            png_destroy_read_struct(&png_ptr, &info_ptr, 0);
12069596a2c1Sopenharmony_ci            CloseFile(fp);
12079596a2c1Sopenharmony_ci        } catch(...) {
12089596a2c1Sopenharmony_ci            png_destroy_read_struct(&png_ptr, &info_ptr, 0);
12099596a2c1Sopenharmony_ci            CloseFile(fp);
12109596a2c1Sopenharmony_ci        }
12119596a2c1Sopenharmony_ci    }
12129596a2c1Sopenharmony_ci}
12139596a2c1Sopenharmony_ci
12149596a2c1Sopenharmony_ciint I18nTimeZone::InitPngptr(png_structp &png_ptr, png_infop &info_ptr, FILE **fp,
12159596a2c1Sopenharmony_ci                             std::string preferredPath)
12169596a2c1Sopenharmony_ci{
12179596a2c1Sopenharmony_ci    bool validFilePath = CheckTzDataFilePath(preferredPath);
12189596a2c1Sopenharmony_ci    if (!validFilePath) {
12199596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("timezone data filepath invalid.");
12209596a2c1Sopenharmony_ci        return 1;
12219596a2c1Sopenharmony_ci    }
12229596a2c1Sopenharmony_ci    *fp = fopen(preferredPath.c_str(), "rb");
12239596a2c1Sopenharmony_ci    if (*fp == NULL) {
12249596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("timezone data resource file not exists.");
12259596a2c1Sopenharmony_ci        return 1;
12269596a2c1Sopenharmony_ci    }
12279596a2c1Sopenharmony_ci    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
12289596a2c1Sopenharmony_ci    if (!png_ptr) {
12299596a2c1Sopenharmony_ci        png_destroy_read_struct(&png_ptr, &info_ptr, 0);
12309596a2c1Sopenharmony_ci        CloseFile(*fp);
12319596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("create read_struct failed.");
12329596a2c1Sopenharmony_ci        return 1;
12339596a2c1Sopenharmony_ci    }
12349596a2c1Sopenharmony_ci    info_ptr = png_create_info_struct(png_ptr);
12359596a2c1Sopenharmony_ci    if (!info_ptr) {
12369596a2c1Sopenharmony_ci        png_destroy_read_struct(&png_ptr, &info_ptr, 0);
12379596a2c1Sopenharmony_ci        CloseFile(*fp);
12389596a2c1Sopenharmony_ci        HILOG_ERROR_I18N("create info_struct failed.");
12399596a2c1Sopenharmony_ci        return 1;
12409596a2c1Sopenharmony_ci    }
12419596a2c1Sopenharmony_ci    return 0;
12429596a2c1Sopenharmony_ci}
12439596a2c1Sopenharmony_ci
12449596a2c1Sopenharmony_cistd::string I18nTimeZone::GetPreferredPath(const double x,
12459596a2c1Sopenharmony_ci                                           const std::vector<std::string> &filePaths)
12469596a2c1Sopenharmony_ci{
12479596a2c1Sopenharmony_ci    if (filePaths.size() == 1) {
12489596a2c1Sopenharmony_ci        return filePaths.at(0);
12499596a2c1Sopenharmony_ci    } else {
12509596a2c1Sopenharmony_ci        int fixedX = (int)(x + TZ_X_PLUS);
12519596a2c1Sopenharmony_ci        for (unsigned int i = 0; i < filePaths.size(); i++) {
12529596a2c1Sopenharmony_ci            std::string path = filePaths.at(i);
12539596a2c1Sopenharmony_ci            std::string left = path.substr(path.find("-") + 1, 3);
12549596a2c1Sopenharmony_ci            std::string right = path.substr(path.find("-") + 4, 3);
12559596a2c1Sopenharmony_ci            if (fixedX >= atoi(left.c_str()) && fixedX < atoi(right.c_str())) {
12569596a2c1Sopenharmony_ci                return path;
12579596a2c1Sopenharmony_ci            }
12589596a2c1Sopenharmony_ci        }
12599596a2c1Sopenharmony_ci        return "";
12609596a2c1Sopenharmony_ci    }
12619596a2c1Sopenharmony_ci}
12629596a2c1Sopenharmony_ci
12639596a2c1Sopenharmony_cistd::vector<std::string> I18nTimeZone::FindTzData()
12649596a2c1Sopenharmony_ci{
12659596a2c1Sopenharmony_ci    using std::filesystem::directory_iterator;
12669596a2c1Sopenharmony_ci    std::map<std::string, std::vector<std::string>> pathMap;
12679596a2c1Sopenharmony_ci    std::regex reg("tz_[0-9]{7}-(\\d{6})\\.dat");
12689596a2c1Sopenharmony_ci    std::regex regVersion("_[0-9]{7}");
12699596a2c1Sopenharmony_ci    const std::vector<std::filesystem::path> pixelPaths = {TZ_PIXEL_PATH, DISTRO_TZ_PIXEL_PATH};
12709596a2c1Sopenharmony_ci    for (const auto& pixelPath : pixelPaths) {
12719596a2c1Sopenharmony_ci        if (!FileExist(pixelPath)) {
12729596a2c1Sopenharmony_ci            HILOG_INFO_I18N("pixelPaths does not exists: %{public}s.", pixelPath.c_str());
12739596a2c1Sopenharmony_ci            continue;
12749596a2c1Sopenharmony_ci        }
12759596a2c1Sopenharmony_ci
12769596a2c1Sopenharmony_ci        for (const auto& entry : directory_iterator{pixelPath}) {
12779596a2c1Sopenharmony_ci            const std::string path = entry.path();
12789596a2c1Sopenharmony_ci            std::smatch match;
12799596a2c1Sopenharmony_ci            bool found = RegexSearchNoExcept(path, match, reg);
12809596a2c1Sopenharmony_ci            bool hasVerison = RegexSearchNoExcept(path, match, regVersion);
12819596a2c1Sopenharmony_ci            if (found && hasVerison) {
12829596a2c1Sopenharmony_ci                std::string version = match[0].str();
12839596a2c1Sopenharmony_ci                SetVersionPathMap(version, path, &pathMap);
12849596a2c1Sopenharmony_ci            }
12859596a2c1Sopenharmony_ci        }
12869596a2c1Sopenharmony_ci    }
12879596a2c1Sopenharmony_ci    std::vector<std::string> filePaths;
12889596a2c1Sopenharmony_ci    std::map<std::string, std::vector<std::string>>::reverse_iterator iter;
12899596a2c1Sopenharmony_ci    for (iter = pathMap.rbegin(); iter != pathMap.rend(); ++iter) {
12909596a2c1Sopenharmony_ci        if (ValidateDataIntegrity(iter->second)) {
12919596a2c1Sopenharmony_ci            return iter->second;
12929596a2c1Sopenharmony_ci        }
12939596a2c1Sopenharmony_ci    }
12949596a2c1Sopenharmony_ci    return filePaths;
12959596a2c1Sopenharmony_ci}
12969596a2c1Sopenharmony_ci
12979596a2c1Sopenharmony_cibool I18nTimeZone::ValidateDataIntegrity(const std::vector<std::string> &pathList)
12989596a2c1Sopenharmony_ci{
12999596a2c1Sopenharmony_ci    size_t total = 0;
13009596a2c1Sopenharmony_ci    for (unsigned int i = 0; i < pathList.size(); i++) {
13019596a2c1Sopenharmony_ci        std::string path = pathList.at(i);
13029596a2c1Sopenharmony_ci        std::string left = path.substr(path.find("-") + 1, 3);
13039596a2c1Sopenharmony_ci        std::string right = path.substr(path.find("-") + 4, 3);
13049596a2c1Sopenharmony_ci        int height = abs(atoi(right.c_str()) - atoi(left.c_str()));
13059596a2c1Sopenharmony_ci        total += static_cast<size_t>(height);
13069596a2c1Sopenharmony_ci    }
13079596a2c1Sopenharmony_ci    return total == TZ_X_PLUS * TZ_HALF_OF_SIZE;
13089596a2c1Sopenharmony_ci}
13099596a2c1Sopenharmony_ci
13109596a2c1Sopenharmony_civoid I18nTimeZone::SetVersionPathMap(std::string verison, std::string path,
13119596a2c1Sopenharmony_ci                                     std::map<std::string, std::vector<std::string>> *pathMap)
13129596a2c1Sopenharmony_ci{
13139596a2c1Sopenharmony_ci    if (pathMap == nullptr) {
13149596a2c1Sopenharmony_ci        return;
13159596a2c1Sopenharmony_ci    }
13169596a2c1Sopenharmony_ci    if (pathMap->find(verison) != pathMap->end()) {
13179596a2c1Sopenharmony_ci        std::vector<std::string> *list = &(pathMap->find(verison)->second);
13189596a2c1Sopenharmony_ci        list->push_back(path);
13199596a2c1Sopenharmony_ci    } else {
13209596a2c1Sopenharmony_ci        std::vector<std::string> list;
13219596a2c1Sopenharmony_ci        list.push_back(path);
13229596a2c1Sopenharmony_ci        pathMap->insert(std::pair<std::string, std::vector<std::string>>(verison, list));
13239596a2c1Sopenharmony_ci    }
13249596a2c1Sopenharmony_ci}
13259596a2c1Sopenharmony_ci
13269596a2c1Sopenharmony_civoid I18nTimeZone::CloseFile(FILE *fp)
13279596a2c1Sopenharmony_ci{
13289596a2c1Sopenharmony_ci    if (fp != nullptr && fp != NULL) {
13299596a2c1Sopenharmony_ci        fclose(fp);
13309596a2c1Sopenharmony_ci    }
13319596a2c1Sopenharmony_ci}
13329596a2c1Sopenharmony_ci
13339596a2c1Sopenharmony_cibool I18nTimeZone::ParamExceedScope(const int x, const int y, int fixedX, int fixedY)
13349596a2c1Sopenharmony_ci{
13359596a2c1Sopenharmony_ci    if (x < 0 || y < 0 || fixedX == 0 || fixedY == 0) {
13369596a2c1Sopenharmony_ci        return true;
13379596a2c1Sopenharmony_ci    }
13389596a2c1Sopenharmony_ci    if (x > (fixedX - 1) || y > (fixedY - 1)) {
13399596a2c1Sopenharmony_ci        return true;
13409596a2c1Sopenharmony_ci    }
13419596a2c1Sopenharmony_ci    return false;
13429596a2c1Sopenharmony_ci}
13439596a2c1Sopenharmony_ci
13449596a2c1Sopenharmony_ciconst char *I18nTimeZone::GetDeviceCityDisplayNamePath()
13459596a2c1Sopenharmony_ci{
13469596a2c1Sopenharmony_ci    struct stat s;
13479596a2c1Sopenharmony_ci    if (stat(DISTRO_ROOT_DISPLAYNAME_PATH, &s) == 0) {
13489596a2c1Sopenharmony_ci        return DISTRO_DEVICE_CITY_DISPLAYNAME_PATH;
13499596a2c1Sopenharmony_ci    } else if (stat(BASE_DEVICE_CITY_DISPLAYNAME_PATH, &s) == 0) {
13509596a2c1Sopenharmony_ci        return BASE_DEVICE_CITY_DISPLAYNAME_PATH;
13519596a2c1Sopenharmony_ci    } else {
13529596a2c1Sopenharmony_ci        return "";
13539596a2c1Sopenharmony_ci    }
13549596a2c1Sopenharmony_ci}
13559596a2c1Sopenharmony_ci}
13569596a2c1Sopenharmony_ci}
13579596a2c1Sopenharmony_ci}
1358