summaryrefslogtreecommitdiffstats
path: root/venv/lib/python3.9/site-packages/tzlocal/utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'venv/lib/python3.9/site-packages/tzlocal/utils.py')
-rw-r--r--venv/lib/python3.9/site-packages/tzlocal/utils.py127
1 files changed, 127 insertions, 0 deletions
diff --git a/venv/lib/python3.9/site-packages/tzlocal/utils.py b/venv/lib/python3.9/site-packages/tzlocal/utils.py
new file mode 100644
index 00000000..5aca1936
--- /dev/null
+++ b/venv/lib/python3.9/site-packages/tzlocal/utils.py
@@ -0,0 +1,127 @@
+import os
+import time
+import datetime
+import calendar
+import pytz_deprecation_shim as pds
+
+try:
+ import zoneinfo # pragma: no cover
+except ImportError:
+ from backports import zoneinfo # pragma: no cover
+
+from tzlocal import windows_tz
+
+
+class ZoneInfoNotFoundError(pds.UnknownTimeZoneError, zoneinfo.ZoneInfoNotFoundError):
+ """An exception derived from both pytz and zoneinfo
+
+ This exception will be trappable both by pytz expecting clients and
+ zoneinfo expecting clients.
+ """
+
+
+def get_system_offset():
+ """Get system's timezone offset using built-in library time.
+
+ For the Timezone constants (altzone, daylight, timezone, and tzname), the
+ value is determined by the timezone rules in effect at module load time or
+ the last time tzset() is called and may be incorrect for times in the past.
+
+ To keep compatibility with Windows, we're always importing time module here.
+ """
+
+ localtime = calendar.timegm(time.localtime())
+ gmtime = calendar.timegm(time.gmtime())
+ offset = gmtime - localtime
+ # We could get the localtime and gmtime on either side of a second switch
+ # so we check that the difference is less than one minute, because nobody
+ # has that small DST differences.
+ if abs(offset - time.altzone) < 60:
+ return -time.altzone # pragma: no cover
+ else:
+ return -time.timezone # pragma: no cover
+
+
+def get_tz_offset(tz):
+ """Get timezone's offset using built-in function datetime.utcoffset()."""
+ return int(datetime.datetime.now(tz).utcoffset().total_seconds())
+
+
+def assert_tz_offset(tz):
+ """Assert that system's timezone offset equals to the timezone offset found.
+
+ If they don't match, we probably have a misconfiguration, for example, an
+ incorrect timezone set in /etc/timezone file in systemd distributions."""
+ tz_offset = get_tz_offset(tz)
+ system_offset = get_system_offset()
+ if tz_offset != system_offset:
+ msg = (
+ "Timezone offset does not match system offset: {} != {}. "
+ "Please, check your config files."
+ ).format(tz_offset, system_offset)
+ raise ValueError(msg)
+
+
+def _tz_name_from_env(tzenv=None):
+ if tzenv is None:
+ tzenv = os.environ.get("TZ")
+
+ if not tzenv:
+ return None
+
+ if tzenv[0] == ":":
+ tzenv = tzenv[1:]
+
+ if tzenv in windows_tz.tz_win:
+ # Yup, it's a timezone
+ return tzenv
+
+ if os.path.isabs(tzenv) and os.path.exists(tzenv):
+ # It's a file specification, expand it, if possible
+ parts = os.path.realpath(tzenv).split(os.sep)
+
+ # Is it a zone info zone?
+ possible_tz = "/".join(parts[-2:])
+ if possible_tz in windows_tz.tz_win:
+ # Yup, it is
+ return possible_tz
+
+ # Maybe it's a short one, like UTC?
+ if parts[-1] in windows_tz.tz_win:
+ # Indeed
+ return parts[-1]
+
+
+def _tz_from_env(tzenv=None):
+ if tzenv is None:
+ tzenv = os.environ.get("TZ")
+
+ if not tzenv:
+ return None
+
+ # Some weird format that exists:
+ if tzenv[0] == ":":
+ tzenv = tzenv[1:]
+
+ # TZ specifies a file
+ if os.path.isabs(tzenv) and os.path.exists(tzenv):
+ # Try to see if we can figure out the name
+ tzname = _tz_name_from_env(tzenv)
+ if not tzname:
+ # Nope, not a standard timezone name, just take the filename
+ tzname = tzenv.split(os.sep)[-1]
+ with open(tzenv, "rb") as tzfile:
+ zone = zoneinfo.ZoneInfo.from_file(tzfile, key=tzname)
+ return pds.wrap_zone(zone)
+
+ # TZ must specify a zoneinfo zone.
+ try:
+ tz = pds.timezone(tzenv)
+ # That worked, so we return this:
+ return tz
+ except pds.UnknownTimeZoneError:
+ # Nope, it's something like "PST4DST" etc, we can't handle that.
+ raise ZoneInfoNotFoundError(
+ "tzlocal() does not support non-zoneinfo timezones like %s. \n"
+ "Please use a timezone in the form of Continent/City" % tzenv
+ ) from None