mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-08-19 21:03:21 -07:00
Bump apscheduler from 3.8.0 to 3.9.1 (#1675)
* Bump apscheduler from 3.8.0 to 3.9.1 Bumps [apscheduler](https://github.com/agronholm/apscheduler) from 3.8.0 to 3.9.1. - [Release notes](https://github.com/agronholm/apscheduler/releases) - [Changelog](https://github.com/agronholm/apscheduler/blob/3.9.1/docs/versionhistory.rst) - [Commits](https://github.com/agronholm/apscheduler/compare/3.8.0...3.9.1) --- updated-dependencies: - dependency-name: apscheduler dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Update apscheduler==3.9.1 * Update pytz==2022.1 * Add pytz-deprecation-shim==0.1.0.post0 * Update tzdata==2022.1 * Update tzlocal==4.2 * Update requirements.txt Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com> [skip ci]
This commit is contained in:
parent
942e09e59e
commit
54c9214b03
46 changed files with 1029 additions and 223 deletions
|
@ -1,5 +1,13 @@
|
|||
import sys
|
||||
if sys.platform == 'win32':
|
||||
from tzlocal.win32 import get_localzone, reload_localzone
|
||||
|
||||
if sys.platform == "win32":
|
||||
from tzlocal.win32 import (
|
||||
get_localzone,
|
||||
get_localzone_name,
|
||||
reload_localzone,
|
||||
) # pragma: no cover
|
||||
else:
|
||||
from tzlocal.unix import get_localzone, reload_localzone
|
||||
from tzlocal.unix import get_localzone, get_localzone_name, reload_localzone
|
||||
|
||||
|
||||
__all__ = ["get_localzone", "get_localzone_name", "reload_localzone"]
|
||||
|
|
|
@ -1,97 +1,75 @@
|
|||
import os
|
||||
import pytz
|
||||
import re
|
||||
import sys
|
||||
import warnings
|
||||
from datetime import timezone
|
||||
import pytz_deprecation_shim as pds
|
||||
|
||||
from tzlocal import utils
|
||||
|
||||
if sys.version_info >= (3, 9):
|
||||
from zoneinfo import ZoneInfo # pragma: no cover
|
||||
else:
|
||||
from backports.zoneinfo import ZoneInfo # pragma: no cover
|
||||
|
||||
_cache_tz = None
|
||||
_cache_tz_name = None
|
||||
|
||||
|
||||
def _tz_from_env(tzenv):
|
||||
if tzenv[0] == ':':
|
||||
tzenv = tzenv[1:]
|
||||
|
||||
# TZ specifies a file
|
||||
if os.path.isabs(tzenv) and os.path.exists(tzenv):
|
||||
with open(tzenv, 'rb') as tzfile:
|
||||
return pytz.tzfile.build_tzinfo('local', tzfile)
|
||||
|
||||
# TZ specifies a zoneinfo zone.
|
||||
try:
|
||||
tz = pytz.timezone(tzenv)
|
||||
# That worked, so we return this:
|
||||
return tz
|
||||
except pytz.UnknownTimeZoneError:
|
||||
raise pytz.UnknownTimeZoneError(
|
||||
"tzlocal() does not support non-zoneinfo timezones like %s. \n"
|
||||
"Please use a timezone in the form of Continent/City")
|
||||
|
||||
|
||||
def _try_tz_from_env():
|
||||
tzenv = os.environ.get('TZ')
|
||||
if tzenv:
|
||||
try:
|
||||
return _tz_from_env(tzenv)
|
||||
except pytz.UnknownTimeZoneError:
|
||||
pass
|
||||
|
||||
|
||||
def _get_localzone(_root='/'):
|
||||
def _get_localzone_name(_root="/"):
|
||||
"""Tries to find the local timezone configuration.
|
||||
|
||||
This method prefers finding the timezone name and passing that to pytz,
|
||||
over passing in the localtime file, as in the later case the zoneinfo
|
||||
name is unknown.
|
||||
This method finds the timezone name, if it can, or it returns None.
|
||||
|
||||
The parameter _root makes the function look for files like /etc/localtime
|
||||
beneath the _root directory. This is primarily used by the tests.
|
||||
In normal usage you call the function without parameters."""
|
||||
|
||||
tzenv = _try_tz_from_env()
|
||||
# First try the ENV setting.
|
||||
tzenv = utils._tz_name_from_env()
|
||||
if tzenv:
|
||||
return tzenv
|
||||
|
||||
# Are we under Termux on Android?
|
||||
if os.path.exists('/system/bin/getprop'):
|
||||
if os.path.exists(os.path.join(_root, "system/bin/getprop")):
|
||||
import subprocess
|
||||
androidtz = subprocess.check_output(['getprop', 'persist.sys.timezone']).strip().decode()
|
||||
return pytz.timezone(androidtz)
|
||||
|
||||
androidtz = (
|
||||
subprocess.check_output(["getprop", "persist.sys.timezone"])
|
||||
.strip()
|
||||
.decode()
|
||||
)
|
||||
return androidtz
|
||||
|
||||
# Now look for distribution specific configuration files
|
||||
# that contain the timezone name.
|
||||
for configfile in ('etc/timezone', 'var/db/zoneinfo'):
|
||||
|
||||
# Stick all of them in a dict, to compare later.
|
||||
found_configs = {}
|
||||
|
||||
for configfile in ("etc/timezone", "var/db/zoneinfo"):
|
||||
tzpath = os.path.join(_root, configfile)
|
||||
try:
|
||||
with open(tzpath, 'rb') as tzfile:
|
||||
with open(tzpath, "rt") as tzfile:
|
||||
data = tzfile.read()
|
||||
|
||||
# Issue #3 was that /etc/timezone was a zoneinfo file.
|
||||
# That's a misconfiguration, but we need to handle it gracefully:
|
||||
if data[:5] == b'TZif2':
|
||||
continue
|
||||
|
||||
etctz = data.strip().decode()
|
||||
etctz = data.strip('/ \t\r\n')
|
||||
if not etctz:
|
||||
# Empty file, skip
|
||||
continue
|
||||
for etctz in data.decode().splitlines():
|
||||
for etctz in etctz.splitlines():
|
||||
# Get rid of host definitions and comments:
|
||||
if ' ' in etctz:
|
||||
etctz, dummy = etctz.split(' ', 1)
|
||||
if '#' in etctz:
|
||||
etctz, dummy = etctz.split('#', 1)
|
||||
if " " in etctz:
|
||||
etctz, dummy = etctz.split(" ", 1)
|
||||
if "#" in etctz:
|
||||
etctz, dummy = etctz.split("#", 1)
|
||||
if not etctz:
|
||||
continue
|
||||
tz = pytz.timezone(etctz.replace(' ', '_'))
|
||||
if _root == '/':
|
||||
# We are using a file in etc to name the timezone.
|
||||
# Verify that the timezone specified there is actually used:
|
||||
utils.assert_tz_offset(tz)
|
||||
return tz
|
||||
|
||||
except IOError:
|
||||
# File doesn't exist or is a directory
|
||||
found_configs[tzpath] = etctz.replace(" ", "_")
|
||||
|
||||
except (IOError, UnicodeDecodeError):
|
||||
# File doesn't exist or is a directory, or it's a binary file.
|
||||
continue
|
||||
|
||||
# CentOS has a ZONE setting in /etc/sysconfig/clock,
|
||||
|
@ -99,14 +77,14 @@ def _get_localzone(_root='/'):
|
|||
# Gentoo has a TIMEZONE setting in /etc/conf.d/clock
|
||||
# We look through these files for a timezone:
|
||||
|
||||
zone_re = re.compile(r'\s*ZONE\s*=\s*\"')
|
||||
timezone_re = re.compile(r'\s*TIMEZONE\s*=\s*\"')
|
||||
end_re = re.compile('\"')
|
||||
zone_re = re.compile(r"\s*ZONE\s*=\s*\"")
|
||||
timezone_re = re.compile(r"\s*TIMEZONE\s*=\s*\"")
|
||||
end_re = re.compile('"')
|
||||
|
||||
for filename in ('etc/sysconfig/clock', 'etc/conf.d/clock'):
|
||||
for filename in ("etc/sysconfig/clock", "etc/conf.d/clock"):
|
||||
tzpath = os.path.join(_root, filename)
|
||||
try:
|
||||
with open(tzpath, 'rt') as tzfile:
|
||||
with open(tzpath, "rt") as tzfile:
|
||||
data = tzfile.readlines()
|
||||
|
||||
for line in data:
|
||||
|
@ -118,48 +96,108 @@ def _get_localzone(_root='/'):
|
|||
if match is not None:
|
||||
# Some setting existed
|
||||
line = line[match.end():]
|
||||
etctz = line[:end_re.search(line).start()]
|
||||
etctz = line[: end_re.search(line).start()]
|
||||
|
||||
# We found a timezone
|
||||
tz = pytz.timezone(etctz.replace(' ', '_'))
|
||||
if _root == '/':
|
||||
# We are using a file in etc to name the timezone.
|
||||
# Verify that the timezone specified there is actually used:
|
||||
utils.assert_tz_offset(tz)
|
||||
return tz
|
||||
found_configs[tzpath] = etctz.replace(" ", "_")
|
||||
|
||||
except IOError:
|
||||
# File doesn't exist or is a directory
|
||||
except (IOError, UnicodeDecodeError):
|
||||
# UnicodeDecode handles when clock is symlink to /etc/localtime
|
||||
continue
|
||||
|
||||
# systemd distributions use symlinks that include the zone name,
|
||||
# see manpage of localtime(5) and timedatectl(1)
|
||||
tzpath = os.path.join(_root, 'etc/localtime')
|
||||
tzpath = os.path.join(_root, "etc/localtime")
|
||||
if os.path.exists(tzpath) and os.path.islink(tzpath):
|
||||
tzpath = os.path.realpath(tzpath)
|
||||
start = tzpath.find("/")+1
|
||||
etctz = realtzpath = os.path.realpath(tzpath)
|
||||
start = etctz.find("/") + 1
|
||||
while start != 0:
|
||||
tzpath = tzpath[start:]
|
||||
etctz = etctz[start:]
|
||||
try:
|
||||
return pytz.timezone(tzpath)
|
||||
except pytz.UnknownTimeZoneError:
|
||||
pds.timezone(etctz)
|
||||
tzinfo = f"{tzpath} is a symlink to"
|
||||
found_configs[tzinfo] = etctz.replace(" ", "_")
|
||||
except pds.UnknownTimeZoneError:
|
||||
pass
|
||||
start = tzpath.find("/")+1
|
||||
start = etctz.find("/") + 1
|
||||
|
||||
# No explicit setting existed. Use localtime
|
||||
for filename in ('etc/localtime', 'usr/local/etc/localtime'):
|
||||
tzpath = os.path.join(_root, filename)
|
||||
if len(found_configs) > 0:
|
||||
# We found some explicit config of some sort!
|
||||
if len(found_configs) > 1:
|
||||
# Uh-oh, multiple configs. See if they match:
|
||||
unique_tzs = set()
|
||||
zoneinfo = os.path.join(_root, "usr", "share", "zoneinfo")
|
||||
directory_depth = len(zoneinfo.split(os.path.sep))
|
||||
|
||||
if not os.path.exists(tzpath):
|
||||
continue
|
||||
with open(tzpath, 'rb') as tzfile:
|
||||
return pytz.tzfile.build_tzinfo('local', tzfile)
|
||||
for tzname in found_configs.values():
|
||||
# Look them up in /usr/share/zoneinfo, and find what they
|
||||
# really point to:
|
||||
path = os.path.realpath(os.path.join(zoneinfo, *tzname.split("/")))
|
||||
real_zone_name = "/".join(path.split(os.path.sep)[directory_depth:])
|
||||
unique_tzs.add(real_zone_name)
|
||||
|
||||
if len(unique_tzs) != 1:
|
||||
message = "Multiple conflicting time zone configurations found:\n"
|
||||
for key, value in found_configs.items():
|
||||
message += f"{key}: {value}\n"
|
||||
message += "Fix the configuration, or set the time zone in a TZ environment variable.\n"
|
||||
raise utils.ZoneInfoNotFoundError(message)
|
||||
|
||||
# We found exactly one config! Use it.
|
||||
return list(found_configs.values())[0]
|
||||
|
||||
|
||||
def _get_localzone(_root="/"):
|
||||
"""Creates a timezone object from the timezone name.
|
||||
|
||||
If there is no timezone config, it will try to create a file from the
|
||||
localtime timezone, and if there isn't one, it will default to UTC.
|
||||
|
||||
The parameter _root makes the function look for files like /etc/localtime
|
||||
beneath the _root directory. This is primarily used by the tests.
|
||||
In normal usage you call the function without parameters."""
|
||||
|
||||
# First try the ENV setting.
|
||||
tzenv = utils._tz_from_env()
|
||||
if tzenv:
|
||||
return tzenv
|
||||
|
||||
tzname = _get_localzone_name(_root)
|
||||
if tzname is None:
|
||||
# No explicit setting existed. Use localtime
|
||||
for filename in ("etc/localtime", "usr/local/etc/localtime"):
|
||||
tzpath = os.path.join(_root, filename)
|
||||
|
||||
if not os.path.exists(tzpath):
|
||||
continue
|
||||
with open(tzpath, "rb") as tzfile:
|
||||
tz = pds.wrap_zone(ZoneInfo.from_file(tzfile, key="local"))
|
||||
break
|
||||
else:
|
||||
warnings.warn("Can not find any timezone configuration, defaulting to UTC.")
|
||||
tz = timezone.utc
|
||||
else:
|
||||
tz = pds.timezone(tzname)
|
||||
|
||||
if _root == "/":
|
||||
# We are using a file in etc to name the timezone.
|
||||
# Verify that the timezone specified there is actually used:
|
||||
utils.assert_tz_offset(tz)
|
||||
return tz
|
||||
|
||||
|
||||
def get_localzone_name():
|
||||
"""Get the computers configured local timezone name, if any."""
|
||||
global _cache_tz_name
|
||||
if _cache_tz_name is None:
|
||||
_cache_tz_name = _get_localzone_name()
|
||||
|
||||
return _cache_tz_name
|
||||
|
||||
warnings.warn('Can not find any timezone configuration, defaulting to UTC.')
|
||||
return pytz.utc
|
||||
|
||||
def get_localzone():
|
||||
"""Get the computers configured local timezone, if any."""
|
||||
|
||||
global _cache_tz
|
||||
if _cache_tz is None:
|
||||
_cache_tz = _get_localzone()
|
||||
|
@ -169,6 +207,9 @@ def get_localzone():
|
|||
|
||||
def reload_localzone():
|
||||
"""Reload the cached localzone. You need to call this if the timezone has changed."""
|
||||
global _cache_tz_name
|
||||
global _cache_tz
|
||||
_cache_tz_name = _get_localzone_name()
|
||||
_cache_tz = _get_localzone()
|
||||
|
||||
return _cache_tz
|
||||
|
|
|
@ -1,7 +1,24 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
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():
|
||||
|
@ -21,9 +38,9 @@ def get_system_offset():
|
|||
# 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
|
||||
return -time.altzone # pragma: no cover
|
||||
else:
|
||||
return -time.timezone
|
||||
return -time.timezone # pragma: no cover
|
||||
|
||||
|
||||
def get_tz_offset(tz):
|
||||
|
@ -39,8 +56,73 @@ def assert_tz_offset(tz):
|
|||
tz_offset = get_tz_offset(tz)
|
||||
system_offset = get_system_offset()
|
||||
if tz_offset != system_offset:
|
||||
msg = ('Timezone offset does not match system offset: {0} != {1}. '
|
||||
'Please, check your config files.').format(
|
||||
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"
|
||||
) from None
|
||||
|
|
|
@ -1,32 +1,53 @@
|
|||
from datetime import datetime
|
||||
import pytz_deprecation_shim as pds
|
||||
|
||||
try:
|
||||
import _winreg as winreg
|
||||
except ImportError:
|
||||
import winreg
|
||||
|
||||
import pytz
|
||||
|
||||
from tzlocal.windows_tz import win_tz
|
||||
from tzlocal import utils
|
||||
|
||||
_cache_tz = None
|
||||
_cache_tz_name = None
|
||||
|
||||
|
||||
def valuestodict(key):
|
||||
"""Convert a registry key's values to a dictionary."""
|
||||
dict = {}
|
||||
result = {}
|
||||
size = winreg.QueryInfoKey(key)[1]
|
||||
for i in range(size):
|
||||
data = winreg.EnumValue(key, i)
|
||||
dict[data[0]] = data[1]
|
||||
return dict
|
||||
result[data[0]] = data[1]
|
||||
return result
|
||||
|
||||
|
||||
def get_localzone_name():
|
||||
def _get_dst_info(tz):
|
||||
# Find the offset for when it doesn't have DST:
|
||||
dst_offset = std_offset = None
|
||||
has_dst = False
|
||||
year = datetime.now().year
|
||||
for dt in (datetime(year, 1, 1), datetime(year, 6, 1)):
|
||||
if tz.dst(dt).total_seconds() == 0.0:
|
||||
# OK, no DST during winter, get this offset
|
||||
std_offset = tz.utcoffset(dt).total_seconds()
|
||||
else:
|
||||
has_dst = True
|
||||
|
||||
return has_dst, std_offset, dst_offset
|
||||
|
||||
|
||||
def _get_localzone_name():
|
||||
# Windows is special. It has unique time zone names (in several
|
||||
# meanings of the word) available, but unfortunately, they can be
|
||||
# translated to the language of the operating system, so we need to
|
||||
# do a backwards lookup, by going through all time zones and see which
|
||||
# one matches.
|
||||
tzenv = utils._tz_name_from_env()
|
||||
if tzenv:
|
||||
return tzenv
|
||||
|
||||
handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
|
||||
|
||||
TZLOCALKEYNAME = r"SYSTEM\CurrentControlSet\Control\TimeZoneInformation"
|
||||
|
@ -34,44 +55,16 @@ def get_localzone_name():
|
|||
keyvalues = valuestodict(localtz)
|
||||
localtz.Close()
|
||||
|
||||
if 'TimeZoneKeyName' in keyvalues:
|
||||
# Windows 7 (and Vista?)
|
||||
if "TimeZoneKeyName" in keyvalues:
|
||||
# Windows 7 and later
|
||||
|
||||
# For some reason this returns a string with loads of NUL bytes at
|
||||
# least on some systems. I don't know if this is a bug somewhere, I
|
||||
# just work around it.
|
||||
tzkeyname = keyvalues['TimeZoneKeyName'].split('\x00', 1)[0]
|
||||
tzkeyname = keyvalues["TimeZoneKeyName"].split("\x00", 1)[0]
|
||||
else:
|
||||
# Windows 2000 or XP
|
||||
|
||||
# This is the localized name:
|
||||
tzwin = keyvalues['StandardName']
|
||||
|
||||
# Open the list of timezones to look up the real name:
|
||||
TZKEYNAME = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"
|
||||
tzkey = winreg.OpenKey(handle, TZKEYNAME)
|
||||
|
||||
# Now, match this value to Time Zone information
|
||||
tzkeyname = None
|
||||
for i in range(winreg.QueryInfoKey(tzkey)[0]):
|
||||
subkey = winreg.EnumKey(tzkey, i)
|
||||
sub = winreg.OpenKey(tzkey, subkey)
|
||||
data = valuestodict(sub)
|
||||
sub.Close()
|
||||
try:
|
||||
if data['Std'] == tzwin:
|
||||
tzkeyname = subkey
|
||||
break
|
||||
except KeyError:
|
||||
# This timezone didn't have proper configuration.
|
||||
# Ignore it.
|
||||
pass
|
||||
|
||||
tzkey.Close()
|
||||
handle.Close()
|
||||
|
||||
if tzkeyname is None:
|
||||
raise LookupError('Can not find Windows timezone configuration')
|
||||
# Don't support XP any longer
|
||||
raise LookupError("Can not find Windows timezone configuration")
|
||||
|
||||
timezone = win_tz.get(tzkeyname)
|
||||
if timezone is None:
|
||||
|
@ -81,24 +74,64 @@ def get_localzone_name():
|
|||
|
||||
# Return what we have.
|
||||
if timezone is None:
|
||||
raise pytz.UnknownTimeZoneError('Can not find timezone ' + tzkeyname)
|
||||
raise utils.ZoneInfoNotFoundError(tzkeyname)
|
||||
|
||||
if keyvalues.get("DynamicDaylightTimeDisabled", 0) == 1:
|
||||
# DST is disabled, so don't return the timezone name,
|
||||
# instead return Etc/GMT+offset
|
||||
|
||||
tz = pds.timezone(timezone)
|
||||
has_dst, std_offset, dst_offset = _get_dst_info(tz)
|
||||
if not has_dst:
|
||||
# The DST is turned off in the windows configuration,
|
||||
# but this timezone doesn't have DST so it doesn't matter
|
||||
return timezone
|
||||
|
||||
if std_offset is None:
|
||||
raise utils.ZoneInfoNotFoundError(
|
||||
f"{tzkeyname} claims to not have a non-DST time!?")
|
||||
|
||||
if std_offset % 3600:
|
||||
# I can't convert this to an hourly offset
|
||||
raise utils.ZoneInfoNotFoundError(
|
||||
f"tzlocal can't support disabling DST in the {timezone} zone.")
|
||||
|
||||
# This has whole hours as offset, return it as Etc/GMT
|
||||
return f"Etc/GMT{-std_offset//3600:+.0f}"
|
||||
|
||||
return timezone
|
||||
|
||||
|
||||
def get_localzone_name():
|
||||
"""Get the zoneinfo timezone name that matches the Windows-configured timezone."""
|
||||
global _cache_tz_name
|
||||
if _cache_tz_name is None:
|
||||
_cache_tz_name = _get_localzone_name()
|
||||
|
||||
return _cache_tz_name
|
||||
|
||||
|
||||
def get_localzone():
|
||||
"""Returns the zoneinfo-based tzinfo object that matches the Windows-configured timezone."""
|
||||
|
||||
global _cache_tz
|
||||
if _cache_tz is None:
|
||||
_cache_tz = pytz.timezone(get_localzone_name())
|
||||
_cache_tz = pds.timezone(get_localzone_name())
|
||||
|
||||
if not utils._tz_name_from_env():
|
||||
# If the timezone does NOT come from a TZ environment variable,
|
||||
# verify that it's correct. If it's from the environment,
|
||||
# we accept it, this is so you can run tests with different timezones.
|
||||
utils.assert_tz_offset(_cache_tz)
|
||||
|
||||
utils.assert_tz_offset(_cache_tz)
|
||||
return _cache_tz
|
||||
|
||||
|
||||
def reload_localzone():
|
||||
"""Reload the cached localzone. You need to call this if the timezone has changed."""
|
||||
global _cache_tz
|
||||
_cache_tz = pytz.timezone(get_localzone_name())
|
||||
global _cache_tz_name
|
||||
_cache_tz_name = _get_localzone_name()
|
||||
_cache_tz = pds.timezone(_cache_tz_name)
|
||||
utils.assert_tz_offset(_cache_tz)
|
||||
return _cache_tz
|
||||
|
|
|
@ -104,6 +104,7 @@ win_tz = {'AUS Central Standard Time': 'Australia/Darwin',
|
|||
'Saratov Standard Time': 'Europe/Saratov',
|
||||
'Singapore Standard Time': 'Asia/Singapore',
|
||||
'South Africa Standard Time': 'Africa/Johannesburg',
|
||||
'South Sudan Standard Time': 'Africa/Juba',
|
||||
'Sri Lanka Standard Time': 'Asia/Colombo',
|
||||
'Sudan Standard Time': 'Africa/Khartoum',
|
||||
'Syria Standard Time': 'Asia/Damascus',
|
||||
|
@ -118,7 +119,7 @@ win_tz = {'AUS Central Standard Time': 'Australia/Darwin',
|
|||
'Turks And Caicos Standard Time': 'America/Grand_Turk',
|
||||
'US Eastern Standard Time': 'America/Indianapolis',
|
||||
'US Mountain Standard Time': 'America/Phoenix',
|
||||
'UTC': 'Etc/GMT',
|
||||
'UTC': 'Etc/UTC',
|
||||
'UTC+12': 'Etc/GMT-12',
|
||||
'UTC+13': 'Etc/GMT-13',
|
||||
'UTC-02': 'Etc/GMT+2',
|
||||
|
@ -136,7 +137,8 @@ win_tz = {'AUS Central Standard Time': 'Australia/Darwin',
|
|||
'West Asia Standard Time': 'Asia/Tashkent',
|
||||
'West Bank Standard Time': 'Asia/Hebron',
|
||||
'West Pacific Standard Time': 'Pacific/Port_Moresby',
|
||||
'Yakutsk Standard Time': 'Asia/Yakutsk'}
|
||||
'Yakutsk Standard Time': 'Asia/Yakutsk',
|
||||
'Yukon Standard Time': 'America/Whitehorse'}
|
||||
|
||||
# Old name for the win_tz variable:
|
||||
tz_names = win_tz
|
||||
|
@ -166,7 +168,7 @@ tz_win = {'Africa/Abidjan': 'Greenwich Standard Time',
|
|||
'Africa/Gaborone': 'South Africa Standard Time',
|
||||
'Africa/Harare': 'South Africa Standard Time',
|
||||
'Africa/Johannesburg': 'South Africa Standard Time',
|
||||
'Africa/Juba': 'E. Africa Standard Time',
|
||||
'Africa/Juba': 'South Sudan Standard Time',
|
||||
'Africa/Kampala': 'E. Africa Standard Time',
|
||||
'Africa/Khartoum': 'Sudan Standard Time',
|
||||
'Africa/Kigali': 'South Africa Standard Time',
|
||||
|
@ -234,8 +236,8 @@ tz_win = {'Africa/Abidjan': 'Greenwich Standard Time',
|
|||
'America/Creston': 'US Mountain Standard Time',
|
||||
'America/Cuiaba': 'Central Brazilian Standard Time',
|
||||
'America/Curacao': 'SA Western Standard Time',
|
||||
'America/Danmarkshavn': 'UTC',
|
||||
'America/Dawson': 'Pacific Standard Time',
|
||||
'America/Danmarkshavn': 'Greenwich Standard Time',
|
||||
'America/Dawson': 'Yukon Standard Time',
|
||||
'America/Dawson_Creek': 'US Mountain Standard Time',
|
||||
'America/Denver': 'Mountain Standard Time',
|
||||
'America/Detroit': 'Eastern Standard Time',
|
||||
|
@ -345,14 +347,14 @@ tz_win = {'Africa/Abidjan': 'Greenwich Standard Time',
|
|||
'America/Tortola': 'SA Western Standard Time',
|
||||
'America/Vancouver': 'Pacific Standard Time',
|
||||
'America/Virgin': 'SA Western Standard Time',
|
||||
'America/Whitehorse': 'Pacific Standard Time',
|
||||
'America/Whitehorse': 'Yukon Standard Time',
|
||||
'America/Winnipeg': 'Central Standard Time',
|
||||
'America/Yakutat': 'Alaskan Standard Time',
|
||||
'America/Yellowknife': 'Mountain Standard Time',
|
||||
'Antarctica/Casey': 'Singapore Standard Time',
|
||||
'Antarctica/Casey': 'Central Pacific Standard Time',
|
||||
'Antarctica/Davis': 'SE Asia Standard Time',
|
||||
'Antarctica/DumontDUrville': 'West Pacific Standard Time',
|
||||
'Antarctica/Macquarie': 'Central Pacific Standard Time',
|
||||
'Antarctica/Macquarie': 'Tasmania Standard Time',
|
||||
'Antarctica/Mawson': 'West Asia Standard Time',
|
||||
'Antarctica/McMurdo': 'New Zealand Standard Time',
|
||||
'Antarctica/Palmer': 'SA Eastern Standard Time',
|
||||
|
@ -501,7 +503,7 @@ tz_win = {'Africa/Abidjan': 'Greenwich Standard Time',
|
|||
'Canada/Newfoundland': 'Newfoundland Standard Time',
|
||||
'Canada/Pacific': 'Pacific Standard Time',
|
||||
'Canada/Saskatchewan': 'Canada Central Standard Time',
|
||||
'Canada/Yukon': 'Pacific Standard Time',
|
||||
'Canada/Yukon': 'Yukon Standard Time',
|
||||
'Chile/Continental': 'Pacific SA Standard Time',
|
||||
'Chile/EasterIsland': 'Easter Island Standard Time',
|
||||
'Cuba': 'Cuba Standard Time',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue