# Author: Zhang Huangbin langmaps = { "en_US": "English (US)", "sq_AL": "Albanian", "ar_SA": "Arabic", "hy_AM": "Armenian", "az_AZ": "Azerbaijani", "bs_BA": "Bosnian (Serbian Latin)", "bg_BG": "Bulgarian", "ca_ES": "Català", "cy_GB": "Cymraeg", "hr_HR": "Croatian (Hrvatski)", "cs_CZ": "Čeština", "da_DK": "Dansk", "de_DE": "Deutsch (Deutsch)", "de_CH": "Deutsch (Schweiz)", "en_GB": "English (GB)", "es_ES": "Español", "eo": "Esperanto", "et_EE": "Estonian", "eu_ES": "Euskara (Basque)", "fi_FI": "Finnish (Suomi)", "nl_BE": "Flemish", "fr_FR": "Français", "gl_ES": "Galego (Galician)", "ka_GE": "Georgian (Kartuli)", "el_GR": "Greek", "he_IL": "Hebrew", "hi_IN": "Hindi", "hu_HU": "Hungarian", "is_IS": "Icelandic", "id_ID": "Indonesian", "ga_IE": "Irish", "it_IT": "Italiano", "ja_JP": "Japanese (日本語)", "ko_KR": "Korean", "ku": "Kurdish (Kurmancî)", "lv_LV": "Latvian", "lt_LT": "Lithuanian", "mk_MK": "Macedonian", "ms_MY": "Malay", "nl_NL": "Netherlands", "ne_NP": "Nepali", "nb_NO": "Norsk (Bokmål)", "nn_NO": "Norsk (Nynorsk)", "fa": "Persian (Farsi)", "pl_PL": "Polski", "pt_BR": "Portuguese (Brazilian)", "pt_PT": "Portuguese (Standard)", "ro_RO": "Romanian", "ru_RU": "Русский", "sr_CS": "Serbian (Cyrillic)", "sr_LT": "Serbian (Latin)", "si_LK": "Sinhala", "sk_SK": "Slovak", "sl_SI": "Slovenian", "sv_SE": "Swedish (Svenska)", "th_TH": "Thai", "tr_TR": "Türkçe", "uk_UA": "Ukrainian", "vi_VN": "Vietnamese", "zh_CN": "简体中文", "zh_TW": "繁體中文", } # All available timezone names and time offsets (in minutes). TIMEZONE_OFFSETS = { "GMT-12:00": -720, "GMT-11:00": -660, "GMT-10:00": -600, "GMT-09:30": -570, "GMT-09:00": -540, "GMT-08:00": -480, "GMT-07:00": -420, "GMT-06:00": -360, "GMT-05:00": -300, "GMT-04:30": -270, "GMT-04:00": -240, "GMT-03:30": -210, "GMT-03:00": -180, "GMT-02:00": -120, "GMT-01:00": -60, "GMT": 0, "GMT+01:00": 60, "GMT+02:00": 120, "GMT+03:00": 180, "GMT+03:30": 210, "GMT+04:00": 240, "GMT+04:30": 270, "GMT+05:00": 300, "GMT+05:30": 330, "GMT+05:45": 345, "GMT+06:00": 360, "GMT+06:30": 390, "GMT+07:00": 420, "GMT+08:00": 480, "GMT+08:45": 525, "GMT+09:00": 540, "GMT+09:30": 570, "GMT+10:00": 600, "GMT+10:30": 630, "GMT+11:00": 660, "GMT+11:30": 690, "GMT+12:00": 720, "GMT+12:45": 765, "GMT+13:00": 780, "GMT+14:00": 840, } TIMEZONES = { "Pacific/Midway": "GMT-11:00", "Pacific/Niue": "GMT-11:00", "Pacific/Pago_Pago": "GMT-11:00", "America/Adak": "GMT-10:00", "Pacific/Honolulu": "GMT-10:00", "Pacific/Johnston": "GMT-10:00", "Pacific/Rarotonga": "GMT-10:00", "Pacific/Tahiti": "GMT-10:00", "Pacific/Marquesas": "GMT-09:30", "America/Anchorage": "GMT-09:00", "America/Juneau": "GMT-09:00", "America/Nome": "GMT-09:00", "America/Sitka": "GMT-09:00", "America/Yakutat": "GMT-09:00", "Pacific/Gambier": "GMT-09:00", "America/Dawson": "GMT-08:00", "America/Los_Angeles": "GMT-08:00", "America/Metlakatla": "GMT-08:00", "America/Santa_Isabel": "GMT-08:00", "America/Tijuana": "GMT-08:00", "America/Vancouver": "GMT-08:00", "America/Whitehorse": "GMT-08:00", "Pacific/Pitcairn": "GMT-08:00", "America/Boise": "GMT-07:00", "America/Cambridge_Bay": "GMT-07:00", "America/Chihuahua": "GMT-07:00", "America/Creston": "GMT-07:00", "America/Dawson_Creek": "GMT-07:00", "America/Denver": "GMT-07:00", "America/Edmonton": "GMT-07:00", "America/Hermosillo": "GMT-07:00", "America/Inuvik": "GMT-07:00", "America/Mazatlan": "GMT-07:00", "America/Ojinaga": "GMT-07:00", "America/Phoenix": "GMT-07:00", "America/Yellowknife": "GMT-07:00", "America/Bahia_Banderas": "GMT-06:00", "America/Belize": "GMT-06:00", "America/Chicago": "GMT-06:00", "America/Costa_Rica": "GMT-06:00", "America/El_Salvador": "GMT-06:00", "America/Guatemala": "GMT-06:00", "America/Indiana/Knox": "GMT-06:00", "America/Indiana/Tell_City": "GMT-06:00", "America/Managua": "GMT-06:00", "America/Matamoros": "GMT-06:00", "America/Menominee": "GMT-06:00", "America/Merida": "GMT-06:00", "America/Mexico_City": "GMT-06:00", "America/Monterrey": "GMT-06:00", "America/North_Dakota/Beulah": "GMT-06:00", "America/North_Dakota/Center": "GMT-06:00", "America/North_Dakota/New_Salem": "GMT-06:00", "America/Rainy_River": "GMT-06:00", "America/Rankin_Inlet": "GMT-06:00", "America/Regina": "GMT-06:00", "America/Resolute": "GMT-06:00", "America/Swift_Current": "GMT-06:00", "America/Tegucigalpa": "GMT-06:00", "America/Winnipeg": "GMT-06:00", "Pacific/Galapagos": "GMT-06:00", "America/Atikokan": "GMT-05:00", "America/Bogota": "GMT-05:00", "America/Cancun": "GMT-05:00", "America/Cayman": "GMT-05:00", "America/Detroit": "GMT-05:00", "America/Eirunepe": "GMT-05:00", "America/Guayaquil": "GMT-05:00", "America/Havana": "GMT-05:00", "America/Indiana/Indianapolis": "GMT-05:00", "America/Indiana/Marengo": "GMT-05:00", "America/Indiana/Petersburg": "GMT-05:00", "America/Indiana/Vevay": "GMT-05:00", "America/Indiana/Vincennes": "GMT-05:00", "America/Indiana/Winamac": "GMT-05:00", "America/Iqaluit": "GMT-05:00", "America/Jamaica": "GMT-05:00", "America/Kentucky/Louisville": "GMT-05:00", "America/Kentucky/Monticello": "GMT-05:00", "America/Lima": "GMT-05:00", "America/Nassau": "GMT-05:00", "America/New_York": "GMT-05:00", "America/Nipigon": "GMT-05:00", "America/Panama": "GMT-05:00", "America/Pangnirtung": "GMT-05:00", "America/Port-au-Prince": "GMT-05:00", "America/Rio_Branco": "GMT-05:00", "America/Thunder_Bay": "GMT-05:00", "America/Toronto": "GMT-05:00", "Pacific/Easter": "GMT-05:00", "America/Caracas": "GMT-04:30", "America/Anguilla": "GMT-04:00", "America/Antigua": "GMT-04:00", "America/Aruba": "GMT-04:00", "America/Barbados": "GMT-04:00", "America/Blanc-Sablon": "GMT-04:00", "America/Boa_Vista": "GMT-04:00", "America/Curacao": "GMT-04:00", "America/Dominica": "GMT-04:00", "America/Glace_Bay": "GMT-04:00", "America/Goose_Bay": "GMT-04:00", "America/Grand_Turk": "GMT-04:00", "America/Grenada": "GMT-04:00", "America/Guadeloupe": "GMT-04:00", "America/Guyana": "GMT-04:00", "America/Halifax": "GMT-04:00", "America/Kralendijk": "GMT-04:00", "America/La_Paz": "GMT-04:00", "America/Lower_Princes": "GMT-04:00", "America/Manaus": "GMT-04:00", "America/Marigot": "GMT-04:00", "America/Martinique": "GMT-04:00", "America/Moncton": "GMT-04:00", "America/Montserrat": "GMT-04:00", "America/Port_of_Spain": "GMT-04:00", "America/Porto_Velho": "GMT-04:00", "America/Puerto_Rico": "GMT-04:00", "America/Santo_Domingo": "GMT-04:00", "America/St_Barthelemy": "GMT-04:00", "America/St_Kitts": "GMT-04:00", "America/St_Lucia": "GMT-04:00", "America/St_Thomas": "GMT-04:00", "America/St_Vincent": "GMT-04:00", "America/Thule": "GMT-04:00", "America/Tortola": "GMT-04:00", "Atlantic/Bermuda": "GMT-04:00", "America/St_Johns": "GMT-03:30", "America/Araguaina": "GMT-03:00", "America/Argentina/Buenos_Aires": "GMT-03:00", "America/Argentina/Catamarca": "GMT-03:00", "America/Argentina/Cordoba": "GMT-03:00", "America/Argentina/Jujuy": "GMT-03:00", "America/Argentina/La_Rioja": "GMT-03:00", "America/Argentina/Mendoza": "GMT-03:00", "America/Argentina/Rio_Gallegos": "GMT-03:00", "America/Argentina/Salta": "GMT-03:00", "America/Argentina/San_Juan": "GMT-03:00", "America/Argentina/San_Luis": "GMT-03:00", "America/Argentina/Tucuman": "GMT-03:00", "America/Argentina/Ushuaia": "GMT-03:00", "America/Asuncion": "GMT-03:00", "America/Bahia": "GMT-03:00", "America/Belem": "GMT-03:00", "America/Campo_Grande": "GMT-03:00", "America/Cayenne": "GMT-03:00", "America/Cuiaba": "GMT-03:00", "America/Fortaleza": "GMT-03:00", "America/Godthab": "GMT-03:00", "America/Maceio": "GMT-03:00", "America/Miquelon": "GMT-03:00", "America/Paramaribo": "GMT-03:00", "America/Recife": "GMT-03:00", "America/Santarem": "GMT-03:00", "America/Santiago": "GMT-03:00", "Antarctica/Palmer": "GMT-03:00", "Antarctica/Rothera": "GMT-03:00", "Atlantic/Stanley": "GMT-03:00", "America/Montevideo": "GMT-02:00", "America/Noronha": "GMT-02:00", "America/Sao_Paulo": "GMT-02:00", "Atlantic/South_Georgia": "GMT-02:00", "America/Scoresbysund": "GMT-01:00", "Atlantic/Azores": "GMT-01:00", "Atlantic/Cape_Verde": "GMT-01:00", "Africa/Abidjan": "GMT+00:00", "Africa/Accra": "GMT+00:00", "Africa/Bamako": "GMT+00:00", "Africa/Banjul": "GMT+00:00", "Africa/Bissau": "GMT+00:00", "Africa/Casablanca": "GMT+00:00", "Africa/Conakry": "GMT+00:00", "Africa/Dakar": "GMT+00:00", "Africa/El_Aaiun": "GMT+00:00", "Africa/Freetown": "GMT+00:00", "Africa/Lome": "GMT+00:00", "Africa/Monrovia": "GMT+00:00", "Africa/Nouakchott": "GMT+00:00", "Africa/Ouagadougou": "GMT+00:00", "Africa/Sao_Tome": "GMT+00:00", "America/Danmarkshavn": "GMT+00:00", "Antarctica/Troll": "GMT+00:00", "Atlantic/Canary": "GMT+00:00", "Atlantic/Faroe": "GMT+00:00", "Atlantic/Madeira": "GMT+00:00", "Atlantic/Reykjavik": "GMT+00:00", "Atlantic/St_Helena": "GMT+00:00", "Europe/Dublin": "GMT+00:00", "Europe/Guernsey": "GMT+00:00", "Europe/Isle_of_Man": "GMT+00:00", "Europe/Jersey": "GMT+00:00", "Europe/Lisbon": "GMT+00:00", "Europe/London": "GMT+00:00", "UTC": "GMT+00:00", "Africa/Algiers": "GMT+01:00", "Africa/Bangui": "GMT+01:00", "Africa/Brazzaville": "GMT+01:00", "Africa/Ceuta": "GMT+01:00", "Africa/Douala": "GMT+01:00", "Africa/Kinshasa": "GMT+01:00", "Africa/Lagos": "GMT+01:00", "Africa/Libreville": "GMT+01:00", "Africa/Luanda": "GMT+01:00", "Africa/Malabo": "GMT+01:00", "Africa/Ndjamena": "GMT+01:00", "Africa/Niamey": "GMT+01:00", "Africa/Porto-Novo": "GMT+01:00", "Africa/Tunis": "GMT+01:00", "Arctic/Longyearbyen": "GMT+01:00", "Europe/Amsterdam": "GMT+01:00", "Europe/Andorra": "GMT+01:00", "Europe/Belgrade": "GMT+01:00", "Europe/Berlin": "GMT+01:00", "Europe/Bratislava": "GMT+01:00", "Europe/Brussels": "GMT+01:00", "Europe/Budapest": "GMT+01:00", "Europe/Busingen": "GMT+01:00", "Europe/Copenhagen": "GMT+01:00", "Europe/Gibraltar": "GMT+01:00", "Europe/Ljubljana": "GMT+01:00", "Europe/Luxembourg": "GMT+01:00", "Europe/Madrid": "GMT+01:00", "Europe/Malta": "GMT+01:00", "Europe/Monaco": "GMT+01:00", "Europe/Oslo": "GMT+01:00", "Europe/Paris": "GMT+01:00", "Europe/Podgorica": "GMT+01:00", "Europe/Prague": "GMT+01:00", "Europe/Rome": "GMT+01:00", "Europe/San_Marino": "GMT+01:00", "Europe/Sarajevo": "GMT+01:00", "Europe/Skopje": "GMT+01:00", "Europe/Stockholm": "GMT+01:00", "Europe/Tirane": "GMT+01:00", "Europe/Vaduz": "GMT+01:00", "Europe/Vatican": "GMT+01:00", "Europe/Vienna": "GMT+01:00", "Europe/Warsaw": "GMT+01:00", "Europe/Zagreb": "GMT+01:00", "Europe/Zurich": "GMT+01:00", "Africa/Blantyre": "GMT+02:00", "Africa/Bujumbura": "GMT+02:00", "Africa/Cairo": "GMT+02:00", "Africa/Gaborone": "GMT+02:00", "Africa/Harare": "GMT+02:00", "Africa/Johannesburg": "GMT+02:00", "Africa/Kigali": "GMT+02:00", "Africa/Lubumbashi": "GMT+02:00", "Africa/Lusaka": "GMT+02:00", "Africa/Maputo": "GMT+02:00", "Africa/Maseru": "GMT+02:00", "Africa/Mbabane": "GMT+02:00", "Africa/Tripoli": "GMT+02:00", "Africa/Windhoek": "GMT+02:00", "Asia/Amman": "GMT+02:00", "Asia/Beirut": "GMT+02:00", "Asia/Damascus": "GMT+02:00", "Asia/Gaza": "GMT+02:00", "Asia/Hebron": "GMT+02:00", "Asia/Jerusalem": "GMT+02:00", "Asia/Nicosia": "GMT+02:00", "Europe/Athens": "GMT+02:00", "Europe/Bucharest": "GMT+02:00", "Europe/Chisinau": "GMT+02:00", "Europe/Helsinki": "GMT+02:00", "Europe/Istanbul": "GMT+03:00", "Europe/Kaliningrad": "GMT+02:00", "Europe/Kiev": "GMT+02:00", "Europe/Mariehamn": "GMT+02:00", "Europe/Riga": "GMT+02:00", "Europe/Sofia": "GMT+02:00", "Europe/Tallinn": "GMT+02:00", "Europe/Uzhgorod": "GMT+02:00", "Europe/Vilnius": "GMT+02:00", "Europe/Zaporozhye": "GMT+02:00", "Africa/Addis_Ababa": "GMT+03:00", "Africa/Asmara": "GMT+03:00", "Africa/Dar_es_Salaam": "GMT+03:00", "Africa/Djibouti": "GMT+03:00", "Africa/Juba": "GMT+03:00", "Africa/Kampala": "GMT+03:00", "Africa/Khartoum": "GMT+03:00", "Africa/Mogadishu": "GMT+03:00", "Africa/Nairobi": "GMT+03:00", "Antarctica/Syowa": "GMT+03:00", "Asia/Aden": "GMT+03:00", "Asia/Baghdad": "GMT+03:00", "Asia/Bahrain": "GMT+03:00", "Asia/Kuwait": "GMT+03:00", "Asia/Qatar": "GMT+03:00", "Asia/Riyadh": "GMT+03:00", "Europe/Minsk": "GMT+03:00", "Europe/Moscow": "GMT+03:00", "Europe/Simferopol": "GMT+03:00", "Europe/Volgograd": "GMT+03:00", "Indian/Antananarivo": "GMT+03:00", "Indian/Comoro": "GMT+03:00", "Indian/Mayotte": "GMT+03:00", "Asia/Tehran": "GMT+03:30", "Asia/Baku": "GMT+04:00", "Asia/Dubai": "GMT+04:00", "Asia/Muscat": "GMT+04:00", "Asia/Tbilisi": "GMT+04:00", "Asia/Yerevan": "GMT+04:00", "Europe/Samara": "GMT+04:00", "Indian/Mahe": "GMT+04:00", "Indian/Mauritius": "GMT+04:00", "Indian/Reunion": "GMT+04:00", "Asia/Kabul": "GMT+04:30", "Antarctica/Mawson": "GMT+05:00", "Asia/Aqtau": "GMT+05:00", "Asia/Aqtobe": "GMT+05:00", "Asia/Ashgabat": "GMT+05:00", "Asia/Dushanbe": "GMT+05:00", "Asia/Karachi": "GMT+05:00", "Asia/Oral": "GMT+05:00", "Asia/Samarkand": "GMT+05:00", "Asia/Tashkent": "GMT+05:00", "Asia/Yekaterinburg": "GMT+05:00", "Indian/Kerguelen": "GMT+05:00", "Indian/Maldives": "GMT+05:00", "Asia/Colombo": "GMT+05:30", "Asia/Kolkata": "GMT+05:30", "Asia/Kathmandu": "GMT+05:45", "Antarctica/Vostok": "GMT+06:00", "Asia/Almaty": "GMT+06:00", "Asia/Bishkek": "GMT+06:00", "Asia/Dhaka": "GMT+06:00", "Asia/Novosibirsk": "GMT+06:00", "Asia/Omsk": "GMT+06:00", "Asia/Qyzylorda": "GMT+06:00", "Asia/Thimphu": "GMT+06:00", "Asia/Urumqi": "GMT+06:00", "Indian/Chagos": "GMT+06:00", "Asia/Rangoon": "GMT+06:30", "Indian/Cocos": "GMT+06:30", "Antarctica/Davis": "GMT+07:00", "Asia/Bangkok": "GMT+07:00", "Asia/Ho_Chi_Minh": "GMT+07:00", "Asia/Hovd": "GMT+07:00", "Asia/Jakarta": "GMT+07:00", "Asia/Krasnoyarsk": "GMT+07:00", "Asia/Novokuznetsk": "GMT+07:00", "Asia/Phnom_Penh": "GMT+07:00", "Asia/Pontianak": "GMT+07:00", "Asia/Vientiane": "GMT+07:00", "Indian/Christmas": "GMT+07:00", "Antarctica/Casey": "GMT+08:00", "Asia/Beijing": "GMT+08:00", "Asia/Brunei": "GMT+08:00", "Asia/Chita": "GMT+08:00", "Asia/Choibalsan": "GMT+08:00", "Asia/Hong_Kong": "GMT+08:00", "Asia/Irkutsk": "GMT+08:00", "Asia/Kuala_Lumpur": "GMT+08:00", "Asia/Kuching": "GMT+08:00", "Asia/Macau": "GMT+08:00", "Asia/Makassar": "GMT+08:00", "Asia/Manila": "GMT+08:00", "Asia/Shanghai": "GMT+08:00", "Asia/Singapore": "GMT+08:00", "Asia/Taipei": "GMT+08:00", "Asia/Ulaanbaatar": "GMT+08:00", "Australia/Perth": "GMT+08:00", "Australia/Eucla": "GMT+08:45", "Asia/Dili": "GMT+09:00", "Asia/Jayapura": "GMT+09:00", "Asia/Khandyga": "GMT+09:00", "Asia/Pyongyang": "GMT+09:00", "Asia/Seoul": "GMT+09:00", "Asia/Tokyo": "GMT+09:00", "Asia/Yakutsk": "GMT+09:00", "Pacific/Palau": "GMT+09:00", "Australia/Darwin": "GMT+09:30", "Antarctica/DumontDUrville": "GMT+10:00", "Asia/Magadan": "GMT+10:00", "Asia/Sakhalin": "GMT+10:00", "Asia/Ust-Nera": "GMT+10:00", "Asia/Vladivostok": "GMT+10:00", "Australia/Brisbane": "GMT+10:00", "Australia/Lindeman": "GMT+10:00", "Pacific/Chuuk": "GMT+10:00", "Pacific/Guam": "GMT+10:00", "Pacific/Port_Moresby": "GMT+10:00", "Pacific/Saipan": "GMT+10:00", "Australia/Sydney": "GMT+10:00", "Australia/Adelaide": "GMT+10:30", "Australia/Broken_Hill": "GMT+10:30", "Antarctica/Macquarie": "GMT+11:00", "Asia/Srednekolymsk": "GMT+11:00", "Australia/Currie": "GMT+11:00", "Australia/Hobart": "GMT+11:00", "Australia/Lord_Howe": "GMT+11:00", "Australia/Melbourne": "GMT+11:00", "Pacific/Bougainville": "GMT+11:00", "Pacific/Efate": "GMT+11:00", "Pacific/Guadalcanal": "GMT+11:00", "Pacific/Kosrae": "GMT+11:00", "Pacific/Noumea": "GMT+11:00", "Pacific/Pohnpei": "GMT+11:00", "Pacific/Norfolk": "GMT+11:30", "Asia/Anadyr": "GMT+12:00", "Asia/Kamchatka": "GMT+12:00", "Pacific/Funafuti": "GMT+12:00", "Pacific/Kwajalein": "GMT+12:00", "Pacific/Majuro": "GMT+12:00", "Pacific/Nauru": "GMT+12:00", "Pacific/Tarawa": "GMT+12:00", "Pacific/Wake": "GMT+12:00", "Pacific/Wallis": "GMT+12:00", "Antarctica/McMurdo": "GMT+13:00", "Pacific/Auckland": "GMT+13:00", "Pacific/Enderbury": "GMT+13:00", "Pacific/Fakaofo": "GMT+13:00", "Pacific/Fiji": "GMT+13:00", "Pacific/Tongatapu": "GMT+13:00", "Pacific/Chatham": "GMT+13:45", "Pacific/Apia": "GMT+14:00", "Pacific/Kiritimati": "GMT+14:00", }