58 lines
1.7 KiB
Python
58 lines
1.7 KiB
Python
|
try:
|
||
|
import pytz
|
||
|
except ModuleNotFoundError:
|
||
|
pytz = None
|
||
|
|
||
|
try:
|
||
|
import zoneinfo
|
||
|
except ModuleNotFoundError:
|
||
|
zoneinfo = None
|
||
|
|
||
|
|
||
|
def _get_tzinfo(tzenv: str):
|
||
|
"""Get the tzinfo from `zoneinfo` or `pytz`
|
||
|
|
||
|
:param tzenv: timezone in the form of Continent/City
|
||
|
:return: tzinfo object or None if not found
|
||
|
"""
|
||
|
if pytz:
|
||
|
try:
|
||
|
return pytz.timezone(tzenv)
|
||
|
except pytz.UnknownTimeZoneError:
|
||
|
pass
|
||
|
else:
|
||
|
try:
|
||
|
return zoneinfo.ZoneInfo(tzenv)
|
||
|
except ValueError as ve:
|
||
|
# This is somewhat hacky, but since _validate_tzfile_path() doesn't
|
||
|
# raise a specific error type, we'll need to check the message to be
|
||
|
# one we know to be from that function.
|
||
|
# If so, we pretend it meant that the TZ didn't exist, for the benefit
|
||
|
# of `babel.localtime` catching the `LookupError` raised by
|
||
|
# `_get_tzinfo_or_raise()`.
|
||
|
# See https://github.com/python-babel/babel/issues/1092
|
||
|
if str(ve).startswith("ZoneInfo keys "):
|
||
|
return None
|
||
|
except zoneinfo.ZoneInfoNotFoundError:
|
||
|
pass
|
||
|
|
||
|
return None
|
||
|
|
||
|
|
||
|
def _get_tzinfo_or_raise(tzenv: str):
|
||
|
tzinfo = _get_tzinfo(tzenv)
|
||
|
if tzinfo is None:
|
||
|
raise LookupError(
|
||
|
f"Can not find timezone {tzenv}. \n"
|
||
|
"Timezone names are generally in the form `Continent/City`.",
|
||
|
)
|
||
|
return tzinfo
|
||
|
|
||
|
|
||
|
def _get_tzinfo_from_file(tzfilename: str):
|
||
|
with open(tzfilename, 'rb') as tzfile:
|
||
|
if pytz:
|
||
|
return pytz.tzfile.build_tzinfo('local', tzfile)
|
||
|
else:
|
||
|
return zoneinfo.ZoneInfo.from_file(tzfile)
|