mirror of https://github.com/zulip/zulip.git
63 lines
2.2 KiB
Python
63 lines
2.2 KiB
Python
import datetime
|
|
from functools import lru_cache
|
|
from io import TextIOWrapper
|
|
from typing import Any, Dict, Union
|
|
|
|
import pytz
|
|
|
|
|
|
@lru_cache(maxsize=None)
|
|
def get_canonical_timezone_map() -> Dict[str, str]:
|
|
canonical = {}
|
|
with TextIOWrapper(
|
|
pytz.open_resource("tzdata.zi") # type: ignore[attr-defined] # Unclear if this is part of the public pytz API
|
|
) as f:
|
|
for line in f:
|
|
if line.startswith("L "):
|
|
l, name, alias = line.split()
|
|
canonical[alias] = name
|
|
return canonical
|
|
|
|
def canonicalize_timezone(key: str) -> str:
|
|
return get_canonical_timezone_map().get(key, key)
|
|
|
|
# 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. It 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).
|
|
@lru_cache(maxsize=None)
|
|
def get_common_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)
|
|
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
|