mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-07 13:41:15 -07:00
Update tzlocal to 2.0.0
This commit is contained in:
parent
b9a80d06e4
commit
2917b609c3
6 changed files with 166 additions and 174 deletions
|
@ -1,6 +1,47 @@
|
|||
Changes
|
||||
=======
|
||||
|
||||
2.0.0 (2019-07-23)
|
||||
------------------
|
||||
|
||||
- No differences since 2.0.0b3
|
||||
|
||||
Major differences since 1.5.1
|
||||
.............................
|
||||
|
||||
- When no time zone configuration can be find, tzlocal now return UTC.
|
||||
This is a major difference from 1.x, where an exception would be raised.
|
||||
This change is because Docker images often have no configuration at all,
|
||||
and the unix utilities will then default to UTC, so we follow that.
|
||||
|
||||
- If tzlocal on Unix finds a timezone name in a /etc config file, then
|
||||
tzlocal now verifies that the timezone it fouds has the same offset as
|
||||
the local computer is configured with. If it doesn't, something is
|
||||
configured incorrectly. (Victor Torres, regebro)
|
||||
|
||||
- Get timezone via Termux `getprop` wrapper on Android. It's not officially
|
||||
supported because we can't test it, but at least we make an effort.
|
||||
(Jean Jordaan)
|
||||
|
||||
Minor differences and bug fixes
|
||||
...............................
|
||||
|
||||
- Skip comment lines when parsing /etc/timezone. (Edward Betts)
|
||||
|
||||
- Don't load timezone from current directory. (Gabriel Corona)
|
||||
|
||||
- Now verifies that the config files actually contain something before
|
||||
reading them. (Zackary Welch, regebro)
|
||||
|
||||
- Got rid of a BytesWarning (Mickaël Schoentgen)
|
||||
|
||||
- Now handles if config file paths exists, but are directories.
|
||||
|
||||
- Moved tests out from distributions
|
||||
|
||||
- Support wheels
|
||||
|
||||
|
||||
1.5.1 (2017-12-01)
|
||||
------------------
|
||||
|
||||
|
@ -38,9 +79,6 @@ Changes
|
|||
------------------
|
||||
|
||||
- Ensure closing of subprocess on OS X (ayalash)
|
||||
DOING: Implementing feedback on the unsubscribe button
|
||||
DOING: Investigating remaining issues with DOCX export
|
||||
BLOCKERS: None
|
||||
|
||||
- Removed unused imports (jwilk)
|
||||
|
||||
|
|
|
@ -1,134 +0,0 @@
|
|||
import mock
|
||||
import os
|
||||
import pytz
|
||||
import sys
|
||||
import tzlocal.unix
|
||||
import unittest
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class TzLocalTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
if 'TZ' in os.environ:
|
||||
del os.environ['TZ']
|
||||
|
||||
self.path = os.path.split(__file__)[0]
|
||||
|
||||
def test_env(self):
|
||||
tz_harare = tzlocal.unix._tz_from_env(':Africa/Harare')
|
||||
self.assertEqual(tz_harare.zone, 'Africa/Harare')
|
||||
|
||||
# Some Unices allow this as well, so we must allow it:
|
||||
tz_harare = tzlocal.unix._tz_from_env('Africa/Harare')
|
||||
self.assertEqual(tz_harare.zone, 'Africa/Harare')
|
||||
|
||||
tz_local = tzlocal.unix._tz_from_env(':' + os.path.join(self.path, 'test_data', 'Harare'))
|
||||
self.assertEqual(tz_local.zone, 'local')
|
||||
# Make sure the local timezone is the same as the Harare one above.
|
||||
# We test this with a past date, so that we don't run into future changes
|
||||
# of the Harare timezone.
|
||||
dt = datetime(2012, 1, 1, 5)
|
||||
self.assertEqual(tz_harare.localize(dt), tz_local.localize(dt))
|
||||
|
||||
# Non-zoneinfo timezones are not supported in the TZ environment.
|
||||
self.assertRaises(pytz.UnknownTimeZoneError, tzlocal.unix._tz_from_env, 'GMT+03:00')
|
||||
|
||||
# Test the _try function
|
||||
os.environ['TZ'] = 'Africa/Harare'
|
||||
tz_harare = tzlocal.unix._try_tz_from_env()
|
||||
self.assertEqual(tz_harare.zone, 'Africa/Harare')
|
||||
# With a zone that doesn't exist
|
||||
os.environ['TZ'] = 'Just Nonsense'
|
||||
tz_harare = tzlocal.unix._try_tz_from_env()
|
||||
self.assertIsNone(tz_harare)
|
||||
|
||||
|
||||
def test_timezone(self):
|
||||
# Most versions of Ubuntu
|
||||
|
||||
tz = tzlocal.unix._get_localzone(_root=os.path.join(self.path, 'test_data', 'timezone'))
|
||||
self.assertEqual(tz.zone, 'Africa/Harare')
|
||||
|
||||
def test_zone_setting(self):
|
||||
# A ZONE setting in /etc/sysconfig/clock, f ex CentOS
|
||||
|
||||
tz = tzlocal.unix._get_localzone(_root=os.path.join(self.path, 'test_data', 'zone_setting'))
|
||||
self.assertEqual(tz.zone, 'Africa/Harare')
|
||||
|
||||
def test_timezone_setting(self):
|
||||
# A ZONE setting in /etc/conf.d/clock, f ex Gentoo
|
||||
|
||||
tz = tzlocal.unix._get_localzone(_root=os.path.join(self.path, 'test_data', 'timezone_setting'))
|
||||
self.assertEqual(tz.zone, 'Africa/Harare')
|
||||
|
||||
def test_symlink_localtime(self):
|
||||
# A ZONE setting in the target path of a symbolic linked localtime, f ex systemd distributions
|
||||
|
||||
tz = tzlocal.unix._get_localzone(_root=os.path.join(self.path, 'test_data', 'symlink_localtime'))
|
||||
self.assertEqual(tz.zone, 'Africa/Harare')
|
||||
|
||||
def test_vardbzoneinfo_setting(self):
|
||||
# A ZONE setting in /etc/conf.d/clock, f ex Gentoo
|
||||
|
||||
tz = tzlocal.unix._get_localzone(_root=os.path.join(self.path, 'test_data', 'vardbzoneinfo'))
|
||||
self.assertEqual(tz.zone, 'Africa/Harare')
|
||||
|
||||
def test_only_localtime(self):
|
||||
tz = tzlocal.unix._get_localzone(_root=os.path.join(self.path, 'test_data', 'localtime'))
|
||||
self.assertEqual(tz.zone, 'local')
|
||||
dt = datetime(2012, 1, 1, 5)
|
||||
self.assertEqual(pytz.timezone('Africa/Harare').localize(dt), tz.localize(dt))
|
||||
|
||||
def test_get_reload(self):
|
||||
os.environ['TZ'] = 'Africa/Harare'
|
||||
tz_harare = tzlocal.unix.get_localzone()
|
||||
self.assertEqual(tz_harare.zone, 'Africa/Harare')
|
||||
# Changing the TZ makes no difference, because it's cached
|
||||
os.environ['TZ'] = 'Africa/Johannesburg'
|
||||
tz_harare = tzlocal.unix.get_localzone()
|
||||
self.assertEqual(tz_harare.zone, 'Africa/Harare')
|
||||
# So we reload it
|
||||
tz_harare = tzlocal.unix.reload_localzone()
|
||||
self.assertEqual(tz_harare.zone, 'Africa/Johannesburg')
|
||||
|
||||
def test_fail(self):
|
||||
with self.assertRaises(pytz.exceptions.UnknownTimeZoneError):
|
||||
tz = tzlocal.unix._get_localzone(_root=os.path.join(self.path, 'test_data'))
|
||||
|
||||
if sys.platform == 'win32':
|
||||
|
||||
import tzlocal.win32
|
||||
class TzWin32Tests(unittest.TestCase):
|
||||
|
||||
def test_win32(self):
|
||||
tzlocal.win32.get_localzone()
|
||||
|
||||
else:
|
||||
|
||||
class TzWin32Tests(unittest.TestCase):
|
||||
|
||||
def test_win32_on_unix(self):
|
||||
# Yes, winreg is all mocked out, but this test means we at least
|
||||
# catch syntax errors, etc.
|
||||
winreg = mock.MagicMock()
|
||||
winreg.OpenKey = mock.MagicMock()
|
||||
winreg.OpenKey.close = mock.MagicMock()
|
||||
winreg.QueryInfoKey = mock.MagicMock(return_value=(1, 1))
|
||||
winreg.EnumValue = mock.MagicMock(
|
||||
return_value=('TimeZoneKeyName','Belarus Standard Time'))
|
||||
winreg.EnumKey = mock.Mock(return_value='Bahia Standard Time')
|
||||
sys.modules['winreg'] = winreg
|
||||
import tzlocal.win32
|
||||
tz = tzlocal.win32.get_localzone()
|
||||
self.assertEqual(tz.zone, 'Europe/Minsk')
|
||||
|
||||
tzlocal.win32.valuestodict = mock.Mock(return_value={
|
||||
'StandardName': 'Mocked Standard Time',
|
||||
'Std': 'Mocked Standard Time',
|
||||
})
|
||||
tz = tzlocal.win32.reload_localzone()
|
||||
self.assertEqual(tz.zone, 'America/Bahia')
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,15 +1,19 @@
|
|||
import os
|
||||
import re
|
||||
import pytz
|
||||
import re
|
||||
import warnings
|
||||
|
||||
from tzlocal import utils
|
||||
|
||||
_cache_tz = None
|
||||
|
||||
|
||||
def _tz_from_env(tzenv):
|
||||
if tzenv[0] == ':':
|
||||
tzenv = tzenv[1:]
|
||||
|
||||
# TZ specifies a file
|
||||
if os.path.exists(tzenv):
|
||||
if os.path.isabs(tzenv) and os.path.exists(tzenv):
|
||||
with open(tzenv, 'rb') as tzfile:
|
||||
return pytz.tzfile.build_tzinfo('local', tzfile)
|
||||
|
||||
|
@ -48,56 +52,85 @@ def _get_localzone(_root='/'):
|
|||
if tzenv:
|
||||
return tzenv
|
||||
|
||||
# Are we under Termux on Android?
|
||||
if os.path.exists('/system/bin/getprop'):
|
||||
import subprocess
|
||||
androidtz = subprocess.check_output(['getprop', 'persist.sys.timezone']).strip().decode()
|
||||
return pytz.timezone(androidtz)
|
||||
|
||||
# Now look for distribution specific configuration files
|
||||
# that contain the timezone name.
|
||||
for configfile in ('etc/timezone', 'var/db/zoneinfo'):
|
||||
tzpath = os.path.join(_root, configfile)
|
||||
if os.path.exists(tzpath):
|
||||
try:
|
||||
with open(tzpath, 'rb') 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] == 'TZif2':
|
||||
if data[:5] == b'TZif2':
|
||||
continue
|
||||
|
||||
etctz = data.strip().decode()
|
||||
# Get rid of host definitions and comments:
|
||||
if ' ' in etctz:
|
||||
etctz, dummy = etctz.split(' ', 1)
|
||||
if '#' in etctz:
|
||||
etctz, dummy = etctz.split('#', 1)
|
||||
return pytz.timezone(etctz.replace(' ', '_'))
|
||||
if not etctz:
|
||||
# Empty file, skip
|
||||
continue
|
||||
for etctz in data.decode().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 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
|
||||
continue
|
||||
|
||||
# CentOS has a ZONE setting in /etc/sysconfig/clock,
|
||||
# OpenSUSE has a TIMEZONE setting in /etc/sysconfig/clock and
|
||||
# Gentoo has a TIMEZONE setting in /etc/conf.d/clock
|
||||
# We look through these files for a timezone:
|
||||
|
||||
zone_re = re.compile('\s*ZONE\s*=\s*\"')
|
||||
timezone_re = re.compile('\s*TIMEZONE\s*=\s*\"')
|
||||
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'):
|
||||
tzpath = os.path.join(_root, filename)
|
||||
if not os.path.exists(tzpath):
|
||||
try:
|
||||
with open(tzpath, 'rt') as tzfile:
|
||||
data = tzfile.readlines()
|
||||
|
||||
for line in data:
|
||||
# Look for the ZONE= setting.
|
||||
match = zone_re.match(line)
|
||||
if match is None:
|
||||
# No ZONE= setting. Look for the TIMEZONE= setting.
|
||||
match = timezone_re.match(line)
|
||||
if match is not None:
|
||||
# Some setting existed
|
||||
line = line[match.end():]
|
||||
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
|
||||
|
||||
except IOError:
|
||||
# File doesn't exist or is a directory
|
||||
continue
|
||||
with open(tzpath, 'rt') as tzfile:
|
||||
data = tzfile.readlines()
|
||||
|
||||
for line in data:
|
||||
# Look for the ZONE= setting.
|
||||
match = zone_re.match(line)
|
||||
if match is None:
|
||||
# No ZONE= setting. Look for the TIMEZONE= setting.
|
||||
match = timezone_re.match(line)
|
||||
if match is not None:
|
||||
# Some setting existed
|
||||
line = line[match.end():]
|
||||
etctz = line[:end_re.search(line).start()]
|
||||
|
||||
# We found a timezone
|
||||
return pytz.timezone(etctz.replace(' ', '_'))
|
||||
|
||||
# systemd distributions use symlinks that include the zone name,
|
||||
# see manpage of localtime(5) and timedatectl(1)
|
||||
|
@ -122,15 +155,18 @@ def _get_localzone(_root='/'):
|
|||
with open(tzpath, 'rb') as tzfile:
|
||||
return pytz.tzfile.build_tzinfo('local', tzfile)
|
||||
|
||||
raise pytz.UnknownTimeZoneError('Can not find any timezone configuration')
|
||||
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()
|
||||
|
||||
return _cache_tz
|
||||
|
||||
|
||||
def reload_localzone():
|
||||
"""Reload the cached localzone. You need to call this if the timezone has changed."""
|
||||
global _cache_tz
|
||||
|
|
38
lib/tzlocal/utils.py
Normal file
38
lib/tzlocal/utils.py
Normal file
|
@ -0,0 +1,38 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import datetime
|
||||
|
||||
|
||||
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.
|
||||
"""
|
||||
import time
|
||||
if time.daylight and time.localtime().tm_isdst > 0:
|
||||
return -time.altzone
|
||||
else:
|
||||
return -time.timezone
|
||||
|
||||
|
||||
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: {0} != {1}. '
|
||||
'Please, check your config files.').format(
|
||||
tz_offset, system_offset
|
||||
)
|
||||
raise ValueError(msg)
|
|
@ -3,11 +3,14 @@ try:
|
|||
except ImportError:
|
||||
import winreg
|
||||
|
||||
from tzlocal.windows_tz import win_tz
|
||||
import pytz
|
||||
|
||||
from tzlocal.windows_tz import win_tz
|
||||
from tzlocal import utils
|
||||
|
||||
_cache_tz = None
|
||||
|
||||
|
||||
def valuestodict(key):
|
||||
"""Convert a registry key's values to a dictionary."""
|
||||
dict = {}
|
||||
|
@ -17,6 +20,7 @@ def valuestodict(key):
|
|||
dict[data[0]] = data[1]
|
||||
return dict
|
||||
|
||||
|
||||
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
|
||||
|
@ -81,15 +85,20 @@ def get_localzone_name():
|
|||
|
||||
return timezone
|
||||
|
||||
|
||||
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())
|
||||
|
||||
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())
|
||||
utils.assert_tz_offset(_cache_tz)
|
||||
return _cache_tz
|
||||
|
|
|
@ -99,10 +99,12 @@ win_tz = {'AUS Central Standard Time': 'Australia/Darwin',
|
|||
'Saint Pierre Standard Time': 'America/Miquelon',
|
||||
'Sakhalin Standard Time': 'Asia/Sakhalin',
|
||||
'Samoa Standard Time': 'Pacific/Apia',
|
||||
'Sao Tome Standard Time': 'Africa/Sao_Tome',
|
||||
'Saratov Standard Time': 'Europe/Saratov',
|
||||
'Singapore Standard Time': 'Asia/Singapore',
|
||||
'South Africa Standard Time': 'Africa/Johannesburg',
|
||||
'Sri Lanka Standard Time': 'Asia/Colombo',
|
||||
'Sudan Standard Time': 'Africa/Khartoum',
|
||||
'Syria Standard Time': 'Asia/Damascus',
|
||||
'Taipei Standard Time': 'Asia/Taipei',
|
||||
'Tasmania Standard Time': 'Australia/Hobart',
|
||||
|
@ -164,7 +166,7 @@ tz_win = {'Africa/Abidjan': 'Greenwich Standard Time',
|
|||
'Africa/Johannesburg': 'South Africa Standard Time',
|
||||
'Africa/Juba': 'E. Africa Standard Time',
|
||||
'Africa/Kampala': 'E. Africa Standard Time',
|
||||
'Africa/Khartoum': 'E. Africa Standard Time',
|
||||
'Africa/Khartoum': 'Sudan Standard Time',
|
||||
'Africa/Kigali': 'South Africa Standard Time',
|
||||
'Africa/Kinshasa': 'W. Central Africa Standard Time',
|
||||
'Africa/Lagos': 'W. Central Africa Standard Time',
|
||||
|
@ -185,7 +187,7 @@ tz_win = {'Africa/Abidjan': 'Greenwich Standard Time',
|
|||
'Africa/Nouakchott': 'Greenwich Standard Time',
|
||||
'Africa/Ouagadougou': 'Greenwich Standard Time',
|
||||
'Africa/Porto-Novo': 'W. Central Africa Standard Time',
|
||||
'Africa/Sao_Tome': 'Greenwich Standard Time',
|
||||
'Africa/Sao_Tome': 'Sao Tome Standard Time',
|
||||
'Africa/Timbuktu': 'Greenwich Standard Time',
|
||||
'Africa/Tripoli': 'Libya Standard Time',
|
||||
'Africa/Tunis': 'W. Central Africa Standard Time',
|
||||
|
@ -285,7 +287,7 @@ tz_win = {'Africa/Abidjan': 'Greenwich Standard Time',
|
|||
'America/Mendoza': 'Argentina Standard Time',
|
||||
'America/Menominee': 'Central Standard Time',
|
||||
'America/Merida': 'Central Standard Time (Mexico)',
|
||||
'America/Metlakatla': 'Alaskan Standard Time',
|
||||
'America/Metlakatla': 'Pacific Standard Time',
|
||||
'America/Mexico_City': 'Central Standard Time (Mexico)',
|
||||
'America/Miquelon': 'Saint Pierre Standard Time',
|
||||
'America/Moncton': 'Atlantic Standard Time',
|
||||
|
@ -345,7 +347,7 @@ tz_win = {'Africa/Abidjan': 'Greenwich Standard Time',
|
|||
'America/Winnipeg': 'Central Standard Time',
|
||||
'America/Yakutat': 'Alaskan Standard Time',
|
||||
'America/Yellowknife': 'Mountain Standard Time',
|
||||
'Antarctica/Casey': 'Central Pacific Standard Time',
|
||||
'Antarctica/Casey': 'W. Australia Standard Time',
|
||||
'Antarctica/Davis': 'SE Asia Standard Time',
|
||||
'Antarctica/DumontDUrville': 'West Pacific Standard Time',
|
||||
'Antarctica/Macquarie': 'Central Pacific Standard Time',
|
||||
|
@ -386,7 +388,7 @@ tz_win = {'Africa/Abidjan': 'Greenwich Standard Time',
|
|||
'Asia/Dili': 'Tokyo Standard Time',
|
||||
'Asia/Dubai': 'Arabian Standard Time',
|
||||
'Asia/Dushanbe': 'West Asia Standard Time',
|
||||
'Asia/Famagusta': 'Turkey Standard Time',
|
||||
'Asia/Famagusta': 'GTB Standard Time',
|
||||
'Asia/Gaza': 'West Bank Standard Time',
|
||||
'Asia/Harbin': 'China Standard Time',
|
||||
'Asia/Hebron': 'West Bank Standard Time',
|
||||
|
@ -421,7 +423,8 @@ tz_win = {'Africa/Abidjan': 'Greenwich Standard Time',
|
|||
'Asia/Pontianak': 'SE Asia Standard Time',
|
||||
'Asia/Pyongyang': 'North Korea Standard Time',
|
||||
'Asia/Qatar': 'Arab Standard Time',
|
||||
'Asia/Qyzylorda': 'Central Asia Standard Time',
|
||||
'Asia/Qostanay': 'Central Asia Standard Time',
|
||||
'Asia/Qyzylorda': 'West Asia Standard Time',
|
||||
'Asia/Rangoon': 'Myanmar Standard Time',
|
||||
'Asia/Riyadh': 'Arab Standard Time',
|
||||
'Asia/Saigon': 'SE Asia Standard Time',
|
||||
|
@ -530,6 +533,7 @@ tz_win = {'Africa/Abidjan': 'Greenwich Standard Time',
|
|||
'Etc/GMT-7': 'SE Asia Standard Time',
|
||||
'Etc/GMT-8': 'Singapore Standard Time',
|
||||
'Etc/GMT-9': 'Tokyo Standard Time',
|
||||
'Etc/UCT': 'UTC',
|
||||
'Etc/UTC': 'UTC',
|
||||
'Europe/Amsterdam': 'W. Europe Standard Time',
|
||||
'Europe/Andorra': 'W. Europe Standard Time',
|
||||
|
@ -673,6 +677,7 @@ tz_win = {'Africa/Abidjan': 'Greenwich Standard Time',
|
|||
'ROK': 'Korea Standard Time',
|
||||
'Singapore': 'Singapore Standard Time',
|
||||
'Turkey': 'Turkey Standard Time',
|
||||
'UCT': 'UTC',
|
||||
'US/Alaska': 'Alaskan Standard Time',
|
||||
'US/Aleutian': 'Aleutian Standard Time',
|
||||
'US/Arizona': 'US Mountain Standard Time',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue