2020-06-11 00:54:34 +02:00
|
|
|
import datetime
|
|
|
|
from typing import Any, Dict, List, Union
|
2017-03-14 10:53:09 +01:00
|
|
|
|
|
|
|
import pytz
|
2020-06-11 00:54:34 +02:00
|
|
|
|
2017-03-14 10:53:09 +01:00
|
|
|
|
2018-05-10 19:13:36 +02:00
|
|
|
def get_all_timezones() -> List[str]:
|
2017-03-14 10:53:09 +01:00
|
|
|
return sorted(pytz.all_timezones)
|
2018-01-04 18:41:34 +01:00
|
|
|
|
2019-07-24 08:19:43 +02:00
|
|
|
def get_timezone(tz: str) -> datetime.tzinfo:
|
2018-01-04 18:41:34 +01:00
|
|
|
return pytz.timezone(tz)
|
2018-07-18 14:36:04 +02:00
|
|
|
|
|
|
|
# This method carefully trims a list of common timezones in the pytz
|
|
|
|
# database and handles duplicate abbreviations in favor of the most
|
|
|
|
# common/popular offset. The output of this can be directly passed as
|
|
|
|
# tz_data to dateutil.parser.
|
|
|
|
def _calculate_timezones() -> Dict[str, Union[int, Any]]:
|
|
|
|
tzdata = {}
|
|
|
|
normal = datetime.datetime(2009, 9, 1) # Any random date is fine here.
|
|
|
|
for str in pytz.all_timezones:
|
|
|
|
tz = pytz.timezone(str)
|
|
|
|
offset = tz.utcoffset(normal).seconds # type: ignore[union-attr] # mypy detects utcoffset returns None.
|
|
|
|
timedelta = tz.utcoffset(normal)
|
|
|
|
if not timedelta:
|
|
|
|
continue
|
|
|
|
offset = timedelta.seconds
|
|
|
|
tz_name = tz.tzname(normal)
|
|
|
|
tzdata[tz_name] = offset
|
|
|
|
# Handle known duplicates/exceptions.
|
|
|
|
# IST: Asia/Kolkata and Europe/Dublin.
|
|
|
|
if tz_name == 'IST':
|
|
|
|
tzdata[tz_name] = 19800 # Asia/Kolkata
|
|
|
|
# CDT: America/AlmostAll and America/Havana.
|
|
|
|
if tz_name == 'CDT':
|
|
|
|
tzdata[tz_name] = -68400 # America/AlmostAll
|
|
|
|
# CST America/Belize -64800
|
|
|
|
# CST America/Costa_Rica -64800
|
|
|
|
# CST America/El_Salvador -64800
|
|
|
|
# CST America/Guatemala -64800
|
|
|
|
# CST America/Managua -64800
|
|
|
|
# CST America/Regina -64800
|
|
|
|
# CST America/Swift_Current -64800
|
|
|
|
# CST America/Tegucigalpa -64800
|
|
|
|
# CST Asia/Macau 28800
|
|
|
|
# CST Asia/Shanghai 28800
|
|
|
|
# CST Asia/Taipei 28800
|
|
|
|
if tz_name == 'CST':
|
|
|
|
tzdata[tz_name] = -64800 # America/All
|
|
|
|
return tzdata
|
|
|
|
|
|
|
|
timezone_data = None
|
|
|
|
|
|
|
|
# _calculate_timezones takes about 25ms to run, so we want to cache
|
|
|
|
# its results (while avoiding running it on process startup since we
|
|
|
|
# only need it for markdown rendering).
|
|
|
|
def get_common_timezones() -> Dict[str, Union[int, Any]]:
|
|
|
|
global timezone_data
|
|
|
|
if timezone_data is None:
|
|
|
|
timezone_data = _calculate_timezones()
|
|
|
|
return timezone_data
|