aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/tzlocal
diff options
context:
space:
mode:
authorvitalyisaev <vitalyisaev@ydb.tech>2023-11-14 09:58:56 +0300
committervitalyisaev <vitalyisaev@ydb.tech>2023-11-14 10:20:20 +0300
commitc2b2dfd9827a400a8495e172a56343462e3ceb82 (patch)
treecd4e4f597d01bede4c82dffeb2d780d0a9046bd0 /contrib/python/tzlocal
parentd4ae8f119e67808cb0cf776ba6e0cf95296f2df7 (diff)
downloadydb-c2b2dfd9827a400a8495e172a56343462e3ceb82.tar.gz
YQ Connector: move tests from yql to ydb (OSS)
Перенос папки с тестами на Коннектор из папки yql в папку ydb (синхронизируется с github).
Diffstat (limited to 'contrib/python/tzlocal')
-rw-r--r--contrib/python/tzlocal/py2/.dist-info/METADATA326
-rw-r--r--contrib/python/tzlocal/py2/.dist-info/top_level.txt1
-rw-r--r--contrib/python/tzlocal/py2/LICENSE.txt19
-rw-r--r--contrib/python/tzlocal/py2/README.rst105
-rw-r--r--contrib/python/tzlocal/py2/tzlocal/__init__.py5
-rw-r--r--contrib/python/tzlocal/py2/tzlocal/unix.py174
-rw-r--r--contrib/python/tzlocal/py2/tzlocal/utils.py46
-rw-r--r--contrib/python/tzlocal/py2/tzlocal/win32.py104
-rw-r--r--contrib/python/tzlocal/py2/tzlocal/windows_tz.py697
-rw-r--r--contrib/python/tzlocal/py2/ya.make34
-rw-r--r--contrib/python/tzlocal/py3/.dist-info/METADATA248
-rw-r--r--contrib/python/tzlocal/py3/.dist-info/top_level.txt1
-rw-r--r--contrib/python/tzlocal/py3/LICENSE.txt19
-rw-r--r--contrib/python/tzlocal/py3/README.rst215
-rw-r--r--contrib/python/tzlocal/py3/tzlocal/__init__.py19
-rw-r--r--contrib/python/tzlocal/py3/tzlocal/py.typed0
-rw-r--r--contrib/python/tzlocal/py3/tzlocal/unix.py231
-rw-r--r--contrib/python/tzlocal/py3/tzlocal/utils.py112
-rw-r--r--contrib/python/tzlocal/py3/tzlocal/win32.py147
-rw-r--r--contrib/python/tzlocal/py3/tzlocal/windows_tz.py736
-rw-r--r--contrib/python/tzlocal/py3/ya.make35
-rw-r--r--contrib/python/tzlocal/ya.make18
22 files changed, 3292 insertions, 0 deletions
diff --git a/contrib/python/tzlocal/py2/.dist-info/METADATA b/contrib/python/tzlocal/py2/.dist-info/METADATA
new file mode 100644
index 0000000000..7bafd427d5
--- /dev/null
+++ b/contrib/python/tzlocal/py2/.dist-info/METADATA
@@ -0,0 +1,326 @@
+Metadata-Version: 2.1
+Name: tzlocal
+Version: 2.1
+Summary: tzinfo object for the local timezone
+Home-page: https://github.com/regebro/tzlocal
+Author: Lennart Regebro
+Author-email: regebro@gmail.com
+License: MIT
+Keywords: timezone pytz
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Operating System :: Microsoft :: Windows
+Classifier: Operating System :: Unix
+Classifier: Operating System :: MacOS :: MacOS X
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Requires-Dist: pytz
+
+tzlocal
+=======
+
+This Python module returns a ``tzinfo`` object with the local timezone information under Unix and Win-32.
+It requires ``pytz``, and returns ``pytz`` ``tzinfo`` objects.
+
+This module attempts to fix a glaring hole in ``pytz``, that there is no way to
+get the local timezone information, unless you know the zoneinfo name, and
+under several Linux distros that's hard or impossible to figure out.
+
+Also, with Windows different timezone system using pytz isn't of much use
+unless you separately configure the zoneinfo timezone name.
+
+With ``tzlocal`` you only need to call ``get_localzone()`` and you will get a
+``tzinfo`` object with the local time zone info. On some Unices you will still
+not get to know what the timezone name is, but you don't need that when you
+have the tzinfo file. However, if the timezone name is readily available it
+will be used.
+
+
+Supported systems
+-----------------
+
+These are the systems that are in theory supported:
+
+ * Windows 2000 and later
+
+ * Any unix-like system with a ``/etc/localtime`` or ``/usr/local/etc/localtime``
+
+If you have one of the above systems and it does not work, it's a bug.
+Please report it.
+
+Please note that if you getting a time zone called ``local``, this is not a bug, it's
+actually the main feature of ``tzlocal``, that even if your system does NOT have a configuration file
+with the zoneinfo name of your time zone, it will still work.
+
+You can also use ``tzlocal`` to get the name of your local timezone, but only if your system is
+configured to make that possible. ``tzlocal`` looks for the timezone name in ``/etc/timezone``, ``/var/db/zoneinfo``,
+``/etc/sysconfig/clock`` and ``/etc/conf.d/clock``. If your ``/etc/localtime`` is a symlink it can also extract the
+name from that symlink.
+
+If you need the name of your local time zone, then please make sure your system is properly configured to allow that.
+If it isn't configured, tzlocal will default to UTC.
+
+Usage
+-----
+
+Load the local timezone:
+
+ >>> from tzlocal import get_localzone
+ >>> tz = get_localzone()
+ >>> tz
+ <DstTzInfo 'Europe/Warsaw' WMT+1:24:00 STD>
+
+Create a local datetime:
+
+ >>> from datetime import datetime
+ >>> dt = tz.localize(datetime(2015, 4, 10, 7, 22))
+ >>> dt
+ datetime.datetime(2015, 4, 10, 7, 22, tzinfo=<DstTzInfo 'Europe/Warsaw' CEST+2:00:00 DST>)
+
+Lookup another timezone with `pytz`:
+
+ >>> import pytz
+ >>> eastern = pytz.timezone('US/Eastern')
+
+Convert the datetime:
+
+ >>> dt.astimezone(eastern)
+ datetime.datetime(2015, 4, 10, 1, 22, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>)
+
+
+Maintainer
+----------
+
+* Lennart Regebro, regebro@gmail.com
+
+Contributors
+------------
+
+* Marc Van Olmen
+* Benjamen Meyer
+* Manuel Ebert
+* Xiaokun Zhu
+* Cameris
+* Edward Betts
+* McK KIM
+* Cris Ewing
+* Ayala Shachar
+* Lev Maximov
+* Jakub Wilk
+* John Quarles
+* Preston Landers
+* Victor Torres
+* Jean Jordaan
+* Zackary Welch
+* Mickaël Schoentgen
+* Gabriel Corona
+
+(Sorry if I forgot someone)
+
+License
+-------
+
+* MIT https://opensource.org/licenses/MIT
+
+
+Changes
+=======
+
+2.1 (2020-05-08)
+----------------
+
+- No changes.
+
+
+2.1b1 (2020-02-08)
+------------------
+
+- The is_dst flag is wrong for Europe/Dublin on some Unix releases.
+ I changed to another way of determining if DST is in effect or not.
+
+- Added support for Python 3.7 and 3.8. Dropped 3.5 although it still works.
+
+
+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)
+------------------
+
+- 1.5 had a bug that slipped through testing, fixed that,
+ increased test coverage.
+
+
+1.5 (2017-11-30)
+----------------
+
+- No longer treats macOS as special, but as a unix.
+
+- get_windows_info.py is renamed to update_windows_mappings.py
+
+- Windows mappings now also contain mappings from deprecated zoneinfo names.
+ (Preston-Landers, regebro)
+
+
+1.4 (2017-04-18)
+----------------
+
+- I use MIT on my other projects, so relicensing.
+
+
+1.4b1 (2017-04-14)
+------------------
+
+- Dropping support for Python versions nobody uses (2.5, 3.1, 3.2), adding 3.6
+ Python 3.1 and 3.2 still works, 2.5 has been broken for some time.
+
+- Ayalash's OS X fix didn't work on Python 2.7, fixed that.
+
+
+1.3.2 (2017-04-12)
+------------------
+
+- Ensure closing of subprocess on OS X (ayalash)
+
+- Removed unused imports (jwilk)
+
+- Closes stdout and stderr to get rid of ResourceWarnings (johnwquarles)
+
+- Updated Windows timezones (axil)
+
+
+1.3 (2016-10-15)
+----------------
+
+- #34: Added support for /var/db/zoneinfo
+
+
+1.2.2 (2016-03-02)
+------------------
+
+- #30: Fixed a bug on OS X.
+
+
+1.2.1 (2016-02-28)
+------------------
+
+- Tests failed if TZ was set in the environment. (EdwardBetts)
+
+- Replaces os.popen() with subprocess.Popen() for OS X to
+ handle when systemsetup doesn't exist. (mckabi, cewing)
+
+
+1.2 (2015-06-14)
+----------------
+
+- Systemd stores no time zone name, forcing us to look at the name of the file
+ that localtime symlinks to. (cameris)
+
+
+1.1.2 (2014-10-18)
+------------------
+
+- Timezones that has 3 items did not work on Mac OS X.
+ (Marc Van Olmen)
+
+- Now doesn't fail if the TZ environment variable isn't an Olsen time zone.
+
+- Some timezones on Windows can apparently be empty (perhaps the are deleted).
+ Now these are ignored.
+ (Xiaokun Zhu)
+
+
+1.1.1 (2014-01-29)
+------------------
+
+- I forgot to add Etc/UTC as an alias for Etc/GMT.
+
+
+1.1 (2014-01-28)
+----------------
+
+- Adding better support for OS X.
+
+- Added support to map from tzdata/Olsen names to Windows names.
+ (Thanks to Benjamen Meyer).
+
+
+1.0 (2013-05-29)
+----------------
+
+- Fixed some more cases where spaces needs replacing with underscores.
+
+- Better handling of misconfigured /etc/timezone.
+
+- Better error message on Windows if we can't find a timezone at all.
+
+
+0.3 (2012-09-13)
+----------------
+
+- Windows 7 support.
+
+- Python 2.5 supported; because it only needed a __future__ import.
+
+- Python 3.3 tested, it worked.
+
+- Got rid of relative imports, because I don't actually like them,
+ so I don't know why I used them in the first place.
+
+- For each Windows zone, use the default zoneinfo zone, not the last one.
+
+
+0.2 (2012-09-12)
+----------------
+
+- Python 3 support.
+
+
+0.1 (2012-09-11)
+----------------
+
+- Initial release.
+
+
diff --git a/contrib/python/tzlocal/py2/.dist-info/top_level.txt b/contrib/python/tzlocal/py2/.dist-info/top_level.txt
new file mode 100644
index 0000000000..cd5e9b12a4
--- /dev/null
+++ b/contrib/python/tzlocal/py2/.dist-info/top_level.txt
@@ -0,0 +1 @@
+tzlocal
diff --git a/contrib/python/tzlocal/py2/LICENSE.txt b/contrib/python/tzlocal/py2/LICENSE.txt
new file mode 100644
index 0000000000..9be1d2fe59
--- /dev/null
+++ b/contrib/python/tzlocal/py2/LICENSE.txt
@@ -0,0 +1,19 @@
+Copyright 2011-2017 Lennart Regebro
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/contrib/python/tzlocal/py2/README.rst b/contrib/python/tzlocal/py2/README.rst
new file mode 100644
index 0000000000..eaa0bdd813
--- /dev/null
+++ b/contrib/python/tzlocal/py2/README.rst
@@ -0,0 +1,105 @@
+tzlocal
+=======
+
+This Python module returns a ``tzinfo`` object with the local timezone information under Unix and Win-32.
+It requires ``pytz``, and returns ``pytz`` ``tzinfo`` objects.
+
+This module attempts to fix a glaring hole in ``pytz``, that there is no way to
+get the local timezone information, unless you know the zoneinfo name, and
+under several Linux distros that's hard or impossible to figure out.
+
+Also, with Windows different timezone system using pytz isn't of much use
+unless you separately configure the zoneinfo timezone name.
+
+With ``tzlocal`` you only need to call ``get_localzone()`` and you will get a
+``tzinfo`` object with the local time zone info. On some Unices you will still
+not get to know what the timezone name is, but you don't need that when you
+have the tzinfo file. However, if the timezone name is readily available it
+will be used.
+
+
+Supported systems
+-----------------
+
+These are the systems that are in theory supported:
+
+ * Windows 2000 and later
+
+ * Any unix-like system with a ``/etc/localtime`` or ``/usr/local/etc/localtime``
+
+If you have one of the above systems and it does not work, it's a bug.
+Please report it.
+
+Please note that if you getting a time zone called ``local``, this is not a bug, it's
+actually the main feature of ``tzlocal``, that even if your system does NOT have a configuration file
+with the zoneinfo name of your time zone, it will still work.
+
+You can also use ``tzlocal`` to get the name of your local timezone, but only if your system is
+configured to make that possible. ``tzlocal`` looks for the timezone name in ``/etc/timezone``, ``/var/db/zoneinfo``,
+``/etc/sysconfig/clock`` and ``/etc/conf.d/clock``. If your ``/etc/localtime`` is a symlink it can also extract the
+name from that symlink.
+
+If you need the name of your local time zone, then please make sure your system is properly configured to allow that.
+If it isn't configured, tzlocal will default to UTC.
+
+Usage
+-----
+
+Load the local timezone:
+
+ >>> from tzlocal import get_localzone
+ >>> tz = get_localzone()
+ >>> tz
+ <DstTzInfo 'Europe/Warsaw' WMT+1:24:00 STD>
+
+Create a local datetime:
+
+ >>> from datetime import datetime
+ >>> dt = tz.localize(datetime(2015, 4, 10, 7, 22))
+ >>> dt
+ datetime.datetime(2015, 4, 10, 7, 22, tzinfo=<DstTzInfo 'Europe/Warsaw' CEST+2:00:00 DST>)
+
+Lookup another timezone with `pytz`:
+
+ >>> import pytz
+ >>> eastern = pytz.timezone('US/Eastern')
+
+Convert the datetime:
+
+ >>> dt.astimezone(eastern)
+ datetime.datetime(2015, 4, 10, 1, 22, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>)
+
+
+Maintainer
+----------
+
+* Lennart Regebro, regebro@gmail.com
+
+Contributors
+------------
+
+* Marc Van Olmen
+* Benjamen Meyer
+* Manuel Ebert
+* Xiaokun Zhu
+* Cameris
+* Edward Betts
+* McK KIM
+* Cris Ewing
+* Ayala Shachar
+* Lev Maximov
+* Jakub Wilk
+* John Quarles
+* Preston Landers
+* Victor Torres
+* Jean Jordaan
+* Zackary Welch
+* Mickaël Schoentgen
+* Gabriel Corona
+
+(Sorry if I forgot someone)
+
+License
+-------
+
+* MIT https://opensource.org/licenses/MIT
diff --git a/contrib/python/tzlocal/py2/tzlocal/__init__.py b/contrib/python/tzlocal/py2/tzlocal/__init__.py
new file mode 100644
index 0000000000..c8196d66d9
--- /dev/null
+++ b/contrib/python/tzlocal/py2/tzlocal/__init__.py
@@ -0,0 +1,5 @@
+import sys
+if sys.platform == 'win32':
+ from tzlocal.win32 import get_localzone, reload_localzone
+else:
+ from tzlocal.unix import get_localzone, reload_localzone
diff --git a/contrib/python/tzlocal/py2/tzlocal/unix.py b/contrib/python/tzlocal/py2/tzlocal/unix.py
new file mode 100644
index 0000000000..8574965a5a
--- /dev/null
+++ b/contrib/python/tzlocal/py2/tzlocal/unix.py
@@ -0,0 +1,174 @@
+import os
+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.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='/'):
+ """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.
+
+ 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()
+ 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)
+ 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] == b'TZif2':
+ continue
+
+ etctz = data.strip().decode()
+ 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(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)
+ 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
+
+ # systemd distributions use symlinks that include the zone name,
+ # see manpage of localtime(5) and timedatectl(1)
+ 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
+ while start != 0:
+ tzpath = tzpath[start:]
+ try:
+ return pytz.timezone(tzpath)
+ except pytz.UnknownTimeZoneError:
+ pass
+ start = tzpath.find("/")+1
+
+ # 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:
+ return pytz.tzfile.build_tzinfo('local', tzfile)
+
+ 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
+ _cache_tz = _get_localzone()
+ return _cache_tz
diff --git a/contrib/python/tzlocal/py2/tzlocal/utils.py b/contrib/python/tzlocal/py2/tzlocal/utils.py
new file mode 100644
index 0000000000..5a6779903d
--- /dev/null
+++ b/contrib/python/tzlocal/py2/tzlocal/utils.py
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+import time
+import datetime
+import calendar
+
+
+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
+ 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)
diff --git a/contrib/python/tzlocal/py2/tzlocal/win32.py b/contrib/python/tzlocal/py2/tzlocal/win32.py
new file mode 100644
index 0000000000..fcc42a23f3
--- /dev/null
+++ b/contrib/python/tzlocal/py2/tzlocal/win32.py
@@ -0,0 +1,104 @@
+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
+
+
+def valuestodict(key):
+ """Convert a registry key's values to a dictionary."""
+ dict = {}
+ size = winreg.QueryInfoKey(key)[1]
+ for i in range(size):
+ data = winreg.EnumValue(key, i)
+ 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
+ # 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.
+ handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
+
+ TZLOCALKEYNAME = r"SYSTEM\CurrentControlSet\Control\TimeZoneInformation"
+ localtz = winreg.OpenKey(handle, TZLOCALKEYNAME)
+ keyvalues = valuestodict(localtz)
+ localtz.Close()
+
+ if 'TimeZoneKeyName' in keyvalues:
+ # Windows 7 (and Vista?)
+
+ # 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]
+ 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')
+
+ timezone = win_tz.get(tzkeyname)
+ if timezone is None:
+ # Nope, that didn't work. Try adding "Standard Time",
+ # it seems to work a lot of times:
+ timezone = win_tz.get(tzkeyname + " Standard Time")
+
+ # Return what we have.
+ if timezone is None:
+ raise pytz.UnknownTimeZoneError('Can not find timezone ' + tzkeyname)
+
+ 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
diff --git a/contrib/python/tzlocal/py2/tzlocal/windows_tz.py b/contrib/python/tzlocal/py2/tzlocal/windows_tz.py
new file mode 100644
index 0000000000..86ba807d06
--- /dev/null
+++ b/contrib/python/tzlocal/py2/tzlocal/windows_tz.py
@@ -0,0 +1,697 @@
+# This file is autogenerated by the update_windows_mapping.py script
+# Do not edit.
+win_tz = {'AUS Central Standard Time': 'Australia/Darwin',
+ 'AUS Eastern Standard Time': 'Australia/Sydney',
+ 'Afghanistan Standard Time': 'Asia/Kabul',
+ 'Alaskan Standard Time': 'America/Anchorage',
+ 'Aleutian Standard Time': 'America/Adak',
+ 'Altai Standard Time': 'Asia/Barnaul',
+ 'Arab Standard Time': 'Asia/Riyadh',
+ 'Arabian Standard Time': 'Asia/Dubai',
+ 'Arabic Standard Time': 'Asia/Baghdad',
+ 'Argentina Standard Time': 'America/Buenos_Aires',
+ 'Astrakhan Standard Time': 'Europe/Astrakhan',
+ 'Atlantic Standard Time': 'America/Halifax',
+ 'Aus Central W. Standard Time': 'Australia/Eucla',
+ 'Azerbaijan Standard Time': 'Asia/Baku',
+ 'Azores Standard Time': 'Atlantic/Azores',
+ 'Bahia Standard Time': 'America/Bahia',
+ 'Bangladesh Standard Time': 'Asia/Dhaka',
+ 'Belarus Standard Time': 'Europe/Minsk',
+ 'Bougainville Standard Time': 'Pacific/Bougainville',
+ 'Canada Central Standard Time': 'America/Regina',
+ 'Cape Verde Standard Time': 'Atlantic/Cape_Verde',
+ 'Caucasus Standard Time': 'Asia/Yerevan',
+ 'Cen. Australia Standard Time': 'Australia/Adelaide',
+ 'Central America Standard Time': 'America/Guatemala',
+ 'Central Asia Standard Time': 'Asia/Almaty',
+ 'Central Brazilian Standard Time': 'America/Cuiaba',
+ 'Central Europe Standard Time': 'Europe/Budapest',
+ 'Central European Standard Time': 'Europe/Warsaw',
+ 'Central Pacific Standard Time': 'Pacific/Guadalcanal',
+ 'Central Standard Time': 'America/Chicago',
+ 'Central Standard Time (Mexico)': 'America/Mexico_City',
+ 'Chatham Islands Standard Time': 'Pacific/Chatham',
+ 'China Standard Time': 'Asia/Shanghai',
+ 'Cuba Standard Time': 'America/Havana',
+ 'Dateline Standard Time': 'Etc/GMT+12',
+ 'E. Africa Standard Time': 'Africa/Nairobi',
+ 'E. Australia Standard Time': 'Australia/Brisbane',
+ 'E. Europe Standard Time': 'Europe/Chisinau',
+ 'E. South America Standard Time': 'America/Sao_Paulo',
+ 'Easter Island Standard Time': 'Pacific/Easter',
+ 'Eastern Standard Time': 'America/New_York',
+ 'Eastern Standard Time (Mexico)': 'America/Cancun',
+ 'Egypt Standard Time': 'Africa/Cairo',
+ 'Ekaterinburg Standard Time': 'Asia/Yekaterinburg',
+ 'FLE Standard Time': 'Europe/Kiev',
+ 'Fiji Standard Time': 'Pacific/Fiji',
+ 'GMT Standard Time': 'Europe/London',
+ 'GTB Standard Time': 'Europe/Bucharest',
+ 'Georgian Standard Time': 'Asia/Tbilisi',
+ 'Greenland Standard Time': 'America/Godthab',
+ 'Greenwich Standard Time': 'Atlantic/Reykjavik',
+ 'Haiti Standard Time': 'America/Port-au-Prince',
+ 'Hawaiian Standard Time': 'Pacific/Honolulu',
+ 'India Standard Time': 'Asia/Calcutta',
+ 'Iran Standard Time': 'Asia/Tehran',
+ 'Israel Standard Time': 'Asia/Jerusalem',
+ 'Jordan Standard Time': 'Asia/Amman',
+ 'Kaliningrad Standard Time': 'Europe/Kaliningrad',
+ 'Korea Standard Time': 'Asia/Seoul',
+ 'Libya Standard Time': 'Africa/Tripoli',
+ 'Line Islands Standard Time': 'Pacific/Kiritimati',
+ 'Lord Howe Standard Time': 'Australia/Lord_Howe',
+ 'Magadan Standard Time': 'Asia/Magadan',
+ 'Magallanes Standard Time': 'America/Punta_Arenas',
+ 'Marquesas Standard Time': 'Pacific/Marquesas',
+ 'Mauritius Standard Time': 'Indian/Mauritius',
+ 'Middle East Standard Time': 'Asia/Beirut',
+ 'Montevideo Standard Time': 'America/Montevideo',
+ 'Morocco Standard Time': 'Africa/Casablanca',
+ 'Mountain Standard Time': 'America/Denver',
+ 'Mountain Standard Time (Mexico)': 'America/Chihuahua',
+ 'Myanmar Standard Time': 'Asia/Rangoon',
+ 'N. Central Asia Standard Time': 'Asia/Novosibirsk',
+ 'Namibia Standard Time': 'Africa/Windhoek',
+ 'Nepal Standard Time': 'Asia/Katmandu',
+ 'New Zealand Standard Time': 'Pacific/Auckland',
+ 'Newfoundland Standard Time': 'America/St_Johns',
+ 'Norfolk Standard Time': 'Pacific/Norfolk',
+ 'North Asia East Standard Time': 'Asia/Irkutsk',
+ 'North Asia Standard Time': 'Asia/Krasnoyarsk',
+ 'North Korea Standard Time': 'Asia/Pyongyang',
+ 'Omsk Standard Time': 'Asia/Omsk',
+ 'Pacific SA Standard Time': 'America/Santiago',
+ 'Pacific Standard Time': 'America/Los_Angeles',
+ 'Pacific Standard Time (Mexico)': 'America/Tijuana',
+ 'Pakistan Standard Time': 'Asia/Karachi',
+ 'Paraguay Standard Time': 'America/Asuncion',
+ 'Qyzylorda Standard Time': 'Asia/Qyzylorda',
+ 'Romance Standard Time': 'Europe/Paris',
+ 'Russia Time Zone 10': 'Asia/Srednekolymsk',
+ 'Russia Time Zone 11': 'Asia/Kamchatka',
+ 'Russia Time Zone 3': 'Europe/Samara',
+ 'Russian Standard Time': 'Europe/Moscow',
+ 'SA Eastern Standard Time': 'America/Cayenne',
+ 'SA Pacific Standard Time': 'America/Bogota',
+ 'SA Western Standard Time': 'America/La_Paz',
+ 'SE Asia Standard Time': 'Asia/Bangkok',
+ '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',
+ 'Tocantins Standard Time': 'America/Araguaina',
+ 'Tokyo Standard Time': 'Asia/Tokyo',
+ 'Tomsk Standard Time': 'Asia/Tomsk',
+ 'Tonga Standard Time': 'Pacific/Tongatapu',
+ 'Transbaikal Standard Time': 'Asia/Chita',
+ 'Turkey Standard Time': 'Europe/Istanbul',
+ 'Turks And Caicos Standard Time': 'America/Grand_Turk',
+ 'US Eastern Standard Time': 'America/Indianapolis',
+ 'US Mountain Standard Time': 'America/Phoenix',
+ 'UTC': 'Etc/GMT',
+ 'UTC+12': 'Etc/GMT-12',
+ 'UTC+13': 'Etc/GMT-13',
+ 'UTC-02': 'Etc/GMT+2',
+ 'UTC-08': 'Etc/GMT+8',
+ 'UTC-09': 'Etc/GMT+9',
+ 'UTC-11': 'Etc/GMT+11',
+ 'Ulaanbaatar Standard Time': 'Asia/Ulaanbaatar',
+ 'Venezuela Standard Time': 'America/Caracas',
+ 'Vladivostok Standard Time': 'Asia/Vladivostok',
+ 'Volgograd Standard Time': 'Europe/Volgograd',
+ 'W. Australia Standard Time': 'Australia/Perth',
+ 'W. Central Africa Standard Time': 'Africa/Lagos',
+ 'W. Europe Standard Time': 'Europe/Berlin',
+ 'W. Mongolia Standard Time': 'Asia/Hovd',
+ 'West Asia Standard Time': 'Asia/Tashkent',
+ 'West Bank Standard Time': 'Asia/Hebron',
+ 'West Pacific Standard Time': 'Pacific/Port_Moresby',
+ 'Yakutsk Standard Time': 'Asia/Yakutsk'}
+
+# Old name for the win_tz variable:
+tz_names = win_tz
+
+tz_win = {'Africa/Abidjan': 'Greenwich Standard Time',
+ 'Africa/Accra': 'Greenwich Standard Time',
+ 'Africa/Addis_Ababa': 'E. Africa Standard Time',
+ 'Africa/Algiers': 'W. Central Africa Standard Time',
+ 'Africa/Asmera': 'E. Africa Standard Time',
+ 'Africa/Bamako': 'Greenwich Standard Time',
+ 'Africa/Bangui': 'W. Central Africa Standard Time',
+ 'Africa/Banjul': 'Greenwich Standard Time',
+ 'Africa/Bissau': 'Greenwich Standard Time',
+ 'Africa/Blantyre': 'South Africa Standard Time',
+ 'Africa/Brazzaville': 'W. Central Africa Standard Time',
+ 'Africa/Bujumbura': 'South Africa Standard Time',
+ 'Africa/Cairo': 'Egypt Standard Time',
+ 'Africa/Casablanca': 'Morocco Standard Time',
+ 'Africa/Ceuta': 'Romance Standard Time',
+ 'Africa/Conakry': 'Greenwich Standard Time',
+ 'Africa/Dakar': 'Greenwich Standard Time',
+ 'Africa/Dar_es_Salaam': 'E. Africa Standard Time',
+ 'Africa/Djibouti': 'E. Africa Standard Time',
+ 'Africa/Douala': 'W. Central Africa Standard Time',
+ 'Africa/El_Aaiun': 'Morocco Standard Time',
+ 'Africa/Freetown': '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/Kampala': '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',
+ 'Africa/Libreville': 'W. Central Africa Standard Time',
+ 'Africa/Lome': 'Greenwich Standard Time',
+ 'Africa/Luanda': 'W. Central Africa Standard Time',
+ 'Africa/Lubumbashi': 'South Africa Standard Time',
+ 'Africa/Lusaka': 'South Africa Standard Time',
+ 'Africa/Malabo': 'W. Central Africa Standard Time',
+ 'Africa/Maputo': 'South Africa Standard Time',
+ 'Africa/Maseru': 'South Africa Standard Time',
+ 'Africa/Mbabane': 'South Africa Standard Time',
+ 'Africa/Mogadishu': 'E. Africa Standard Time',
+ 'Africa/Monrovia': 'Greenwich Standard Time',
+ 'Africa/Nairobi': 'E. Africa Standard Time',
+ 'Africa/Ndjamena': 'W. Central Africa Standard Time',
+ 'Africa/Niamey': 'W. Central Africa Standard Time',
+ 'Africa/Nouakchott': 'Greenwich Standard Time',
+ 'Africa/Ouagadougou': 'Greenwich Standard Time',
+ 'Africa/Porto-Novo': 'W. Central Africa 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',
+ 'Africa/Windhoek': 'Namibia Standard Time',
+ 'America/Adak': 'Aleutian Standard Time',
+ 'America/Anchorage': 'Alaskan Standard Time',
+ 'America/Anguilla': 'SA Western Standard Time',
+ 'America/Antigua': 'SA Western Standard Time',
+ 'America/Araguaina': 'Tocantins Standard Time',
+ 'America/Argentina/La_Rioja': 'Argentina Standard Time',
+ 'America/Argentina/Rio_Gallegos': 'Argentina Standard Time',
+ 'America/Argentina/Salta': 'Argentina Standard Time',
+ 'America/Argentina/San_Juan': 'Argentina Standard Time',
+ 'America/Argentina/San_Luis': 'Argentina Standard Time',
+ 'America/Argentina/Tucuman': 'Argentina Standard Time',
+ 'America/Argentina/Ushuaia': 'Argentina Standard Time',
+ 'America/Aruba': 'SA Western Standard Time',
+ 'America/Asuncion': 'Paraguay Standard Time',
+ 'America/Atka': 'Aleutian Standard Time',
+ 'America/Bahia': 'Bahia Standard Time',
+ 'America/Bahia_Banderas': 'Central Standard Time (Mexico)',
+ 'America/Barbados': 'SA Western Standard Time',
+ 'America/Belem': 'SA Eastern Standard Time',
+ 'America/Belize': 'Central America Standard Time',
+ 'America/Blanc-Sablon': 'SA Western Standard Time',
+ 'America/Boa_Vista': 'SA Western Standard Time',
+ 'America/Bogota': 'SA Pacific Standard Time',
+ 'America/Boise': 'Mountain Standard Time',
+ 'America/Buenos_Aires': 'Argentina Standard Time',
+ 'America/Cambridge_Bay': 'Mountain Standard Time',
+ 'America/Campo_Grande': 'Central Brazilian Standard Time',
+ 'America/Cancun': 'Eastern Standard Time (Mexico)',
+ 'America/Caracas': 'Venezuela Standard Time',
+ 'America/Catamarca': 'Argentina Standard Time',
+ 'America/Cayenne': 'SA Eastern Standard Time',
+ 'America/Cayman': 'SA Pacific Standard Time',
+ 'America/Chicago': 'Central Standard Time',
+ 'America/Chihuahua': 'Mountain Standard Time (Mexico)',
+ 'America/Coral_Harbour': 'SA Pacific Standard Time',
+ 'America/Cordoba': 'Argentina Standard Time',
+ 'America/Costa_Rica': 'Central America 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/Dawson_Creek': 'US Mountain Standard Time',
+ 'America/Denver': 'Mountain Standard Time',
+ 'America/Detroit': 'Eastern Standard Time',
+ 'America/Dominica': 'SA Western Standard Time',
+ 'America/Edmonton': 'Mountain Standard Time',
+ 'America/Eirunepe': 'SA Pacific Standard Time',
+ 'America/El_Salvador': 'Central America Standard Time',
+ 'America/Ensenada': 'Pacific Standard Time (Mexico)',
+ 'America/Fort_Nelson': 'US Mountain Standard Time',
+ 'America/Fortaleza': 'SA Eastern Standard Time',
+ 'America/Glace_Bay': 'Atlantic Standard Time',
+ 'America/Godthab': 'Greenland Standard Time',
+ 'America/Goose_Bay': 'Atlantic Standard Time',
+ 'America/Grand_Turk': 'Turks And Caicos Standard Time',
+ 'America/Grenada': 'SA Western Standard Time',
+ 'America/Guadeloupe': 'SA Western Standard Time',
+ 'America/Guatemala': 'Central America Standard Time',
+ 'America/Guayaquil': 'SA Pacific Standard Time',
+ 'America/Guyana': 'SA Western Standard Time',
+ 'America/Halifax': 'Atlantic Standard Time',
+ 'America/Havana': 'Cuba Standard Time',
+ 'America/Hermosillo': 'US Mountain Standard Time',
+ 'America/Indiana/Knox': 'Central Standard Time',
+ 'America/Indiana/Marengo': 'US Eastern Standard Time',
+ 'America/Indiana/Petersburg': 'Eastern Standard Time',
+ 'America/Indiana/Tell_City': 'Central Standard Time',
+ 'America/Indiana/Vevay': 'US Eastern Standard Time',
+ 'America/Indiana/Vincennes': 'Eastern Standard Time',
+ 'America/Indiana/Winamac': 'Eastern Standard Time',
+ 'America/Indianapolis': 'US Eastern Standard Time',
+ 'America/Inuvik': 'Mountain Standard Time',
+ 'America/Iqaluit': 'Eastern Standard Time',
+ 'America/Jamaica': 'SA Pacific Standard Time',
+ 'America/Jujuy': 'Argentina Standard Time',
+ 'America/Juneau': 'Alaskan Standard Time',
+ 'America/Kentucky/Monticello': 'Eastern Standard Time',
+ 'America/Knox_IN': 'Central Standard Time',
+ 'America/Kralendijk': 'SA Western Standard Time',
+ 'America/La_Paz': 'SA Western Standard Time',
+ 'America/Lima': 'SA Pacific Standard Time',
+ 'America/Los_Angeles': 'Pacific Standard Time',
+ 'America/Louisville': 'Eastern Standard Time',
+ 'America/Lower_Princes': 'SA Western Standard Time',
+ 'America/Maceio': 'SA Eastern Standard Time',
+ 'America/Managua': 'Central America Standard Time',
+ 'America/Manaus': 'SA Western Standard Time',
+ 'America/Marigot': 'SA Western Standard Time',
+ 'America/Martinique': 'SA Western Standard Time',
+ 'America/Matamoros': 'Central Standard Time',
+ 'America/Mazatlan': 'Mountain Standard Time (Mexico)',
+ 'America/Mendoza': 'Argentina Standard Time',
+ 'America/Menominee': 'Central Standard Time',
+ 'America/Merida': 'Central Standard Time (Mexico)',
+ 'America/Metlakatla': 'Alaskan Standard Time',
+ 'America/Mexico_City': 'Central Standard Time (Mexico)',
+ 'America/Miquelon': 'Saint Pierre Standard Time',
+ 'America/Moncton': 'Atlantic Standard Time',
+ 'America/Monterrey': 'Central Standard Time (Mexico)',
+ 'America/Montevideo': 'Montevideo Standard Time',
+ 'America/Montreal': 'Eastern Standard Time',
+ 'America/Montserrat': 'SA Western Standard Time',
+ 'America/Nassau': 'Eastern Standard Time',
+ 'America/New_York': 'Eastern Standard Time',
+ 'America/Nipigon': 'Eastern Standard Time',
+ 'America/Nome': 'Alaskan Standard Time',
+ 'America/Noronha': 'UTC-02',
+ 'America/North_Dakota/Beulah': 'Central Standard Time',
+ 'America/North_Dakota/Center': 'Central Standard Time',
+ 'America/North_Dakota/New_Salem': 'Central Standard Time',
+ 'America/Ojinaga': 'Mountain Standard Time',
+ 'America/Panama': 'SA Pacific Standard Time',
+ 'America/Pangnirtung': 'Eastern Standard Time',
+ 'America/Paramaribo': 'SA Eastern Standard Time',
+ 'America/Phoenix': 'US Mountain Standard Time',
+ 'America/Port-au-Prince': 'Haiti Standard Time',
+ 'America/Port_of_Spain': 'SA Western Standard Time',
+ 'America/Porto_Acre': 'SA Pacific Standard Time',
+ 'America/Porto_Velho': 'SA Western Standard Time',
+ 'America/Puerto_Rico': 'SA Western Standard Time',
+ 'America/Punta_Arenas': 'Magallanes Standard Time',
+ 'America/Rainy_River': 'Central Standard Time',
+ 'America/Rankin_Inlet': 'Central Standard Time',
+ 'America/Recife': 'SA Eastern Standard Time',
+ 'America/Regina': 'Canada Central Standard Time',
+ 'America/Resolute': 'Central Standard Time',
+ 'America/Rio_Branco': 'SA Pacific Standard Time',
+ 'America/Santa_Isabel': 'Pacific Standard Time (Mexico)',
+ 'America/Santarem': 'SA Eastern Standard Time',
+ 'America/Santiago': 'Pacific SA Standard Time',
+ 'America/Santo_Domingo': 'SA Western Standard Time',
+ 'America/Sao_Paulo': 'E. South America Standard Time',
+ 'America/Scoresbysund': 'Azores Standard Time',
+ 'America/Shiprock': 'Mountain Standard Time',
+ 'America/Sitka': 'Alaskan Standard Time',
+ 'America/St_Barthelemy': 'SA Western Standard Time',
+ 'America/St_Johns': 'Newfoundland Standard Time',
+ 'America/St_Kitts': 'SA Western Standard Time',
+ 'America/St_Lucia': 'SA Western Standard Time',
+ 'America/St_Thomas': 'SA Western Standard Time',
+ 'America/St_Vincent': 'SA Western Standard Time',
+ 'America/Swift_Current': 'Canada Central Standard Time',
+ 'America/Tegucigalpa': 'Central America Standard Time',
+ 'America/Thule': 'Atlantic Standard Time',
+ 'America/Thunder_Bay': 'Eastern Standard Time',
+ 'America/Tijuana': 'Pacific Standard Time (Mexico)',
+ 'America/Toronto': 'Eastern 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/Winnipeg': 'Central Standard Time',
+ 'America/Yakutat': 'Alaskan Standard Time',
+ 'America/Yellowknife': 'Mountain Standard Time',
+ 'Antarctica/Casey': 'Singapore Standard Time',
+ 'Antarctica/Davis': 'SE Asia Standard Time',
+ 'Antarctica/DumontDUrville': 'West Pacific Standard Time',
+ 'Antarctica/Macquarie': 'Central Pacific Standard Time',
+ 'Antarctica/Mawson': 'West Asia Standard Time',
+ 'Antarctica/McMurdo': 'New Zealand Standard Time',
+ 'Antarctica/Palmer': 'SA Eastern Standard Time',
+ 'Antarctica/Rothera': 'SA Eastern Standard Time',
+ 'Antarctica/South_Pole': 'New Zealand Standard Time',
+ 'Antarctica/Syowa': 'E. Africa Standard Time',
+ 'Antarctica/Vostok': 'Central Asia Standard Time',
+ 'Arctic/Longyearbyen': 'W. Europe Standard Time',
+ 'Asia/Aden': 'Arab Standard Time',
+ 'Asia/Almaty': 'Central Asia Standard Time',
+ 'Asia/Amman': 'Jordan Standard Time',
+ 'Asia/Anadyr': 'Russia Time Zone 11',
+ 'Asia/Aqtau': 'West Asia Standard Time',
+ 'Asia/Aqtobe': 'West Asia Standard Time',
+ 'Asia/Ashgabat': 'West Asia Standard Time',
+ 'Asia/Ashkhabad': 'West Asia Standard Time',
+ 'Asia/Atyrau': 'West Asia Standard Time',
+ 'Asia/Baghdad': 'Arabic Standard Time',
+ 'Asia/Bahrain': 'Arab Standard Time',
+ 'Asia/Baku': 'Azerbaijan Standard Time',
+ 'Asia/Bangkok': 'SE Asia Standard Time',
+ 'Asia/Barnaul': 'Altai Standard Time',
+ 'Asia/Beirut': 'Middle East Standard Time',
+ 'Asia/Bishkek': 'Central Asia Standard Time',
+ 'Asia/Brunei': 'Singapore Standard Time',
+ 'Asia/Calcutta': 'India Standard Time',
+ 'Asia/Chita': 'Transbaikal Standard Time',
+ 'Asia/Choibalsan': 'Ulaanbaatar Standard Time',
+ 'Asia/Chongqing': 'China Standard Time',
+ 'Asia/Chungking': 'China Standard Time',
+ 'Asia/Colombo': 'Sri Lanka Standard Time',
+ 'Asia/Dacca': 'Bangladesh Standard Time',
+ 'Asia/Damascus': 'Syria Standard Time',
+ 'Asia/Dhaka': 'Bangladesh Standard Time',
+ 'Asia/Dili': 'Tokyo Standard Time',
+ 'Asia/Dubai': 'Arabian Standard Time',
+ 'Asia/Dushanbe': 'West Asia Standard Time',
+ 'Asia/Famagusta': 'GTB Standard Time',
+ 'Asia/Gaza': 'West Bank Standard Time',
+ 'Asia/Harbin': 'China Standard Time',
+ 'Asia/Hebron': 'West Bank Standard Time',
+ 'Asia/Hong_Kong': 'China Standard Time',
+ 'Asia/Hovd': 'W. Mongolia Standard Time',
+ 'Asia/Irkutsk': 'North Asia East Standard Time',
+ 'Asia/Jakarta': 'SE Asia Standard Time',
+ 'Asia/Jayapura': 'Tokyo Standard Time',
+ 'Asia/Jerusalem': 'Israel Standard Time',
+ 'Asia/Kabul': 'Afghanistan Standard Time',
+ 'Asia/Kamchatka': 'Russia Time Zone 11',
+ 'Asia/Karachi': 'Pakistan Standard Time',
+ 'Asia/Kashgar': 'Central Asia Standard Time',
+ 'Asia/Katmandu': 'Nepal Standard Time',
+ 'Asia/Khandyga': 'Yakutsk Standard Time',
+ 'Asia/Krasnoyarsk': 'North Asia Standard Time',
+ 'Asia/Kuala_Lumpur': 'Singapore Standard Time',
+ 'Asia/Kuching': 'Singapore Standard Time',
+ 'Asia/Kuwait': 'Arab Standard Time',
+ 'Asia/Macao': 'China Standard Time',
+ 'Asia/Macau': 'China Standard Time',
+ 'Asia/Magadan': 'Magadan Standard Time',
+ 'Asia/Makassar': 'Singapore Standard Time',
+ 'Asia/Manila': 'Singapore Standard Time',
+ 'Asia/Muscat': 'Arabian Standard Time',
+ 'Asia/Nicosia': 'GTB Standard Time',
+ 'Asia/Novokuznetsk': 'North Asia Standard Time',
+ 'Asia/Novosibirsk': 'N. Central Asia Standard Time',
+ 'Asia/Omsk': 'Omsk Standard Time',
+ 'Asia/Oral': 'West Asia Standard Time',
+ 'Asia/Phnom_Penh': 'SE Asia Standard Time',
+ 'Asia/Pontianak': 'SE Asia Standard Time',
+ 'Asia/Pyongyang': 'North Korea Standard Time',
+ 'Asia/Qatar': 'Arab Standard Time',
+ 'Asia/Qostanay': 'Central Asia Standard Time',
+ 'Asia/Qyzylorda': 'Qyzylorda Standard Time',
+ 'Asia/Rangoon': 'Myanmar Standard Time',
+ 'Asia/Riyadh': 'Arab Standard Time',
+ 'Asia/Saigon': 'SE Asia Standard Time',
+ 'Asia/Sakhalin': 'Sakhalin Standard Time',
+ 'Asia/Samarkand': 'West Asia Standard Time',
+ 'Asia/Seoul': 'Korea Standard Time',
+ 'Asia/Shanghai': 'China Standard Time',
+ 'Asia/Singapore': 'Singapore Standard Time',
+ 'Asia/Srednekolymsk': 'Russia Time Zone 10',
+ 'Asia/Taipei': 'Taipei Standard Time',
+ 'Asia/Tashkent': 'West Asia Standard Time',
+ 'Asia/Tbilisi': 'Georgian Standard Time',
+ 'Asia/Tehran': 'Iran Standard Time',
+ 'Asia/Tel_Aviv': 'Israel Standard Time',
+ 'Asia/Thimbu': 'Bangladesh Standard Time',
+ 'Asia/Thimphu': 'Bangladesh Standard Time',
+ 'Asia/Tokyo': 'Tokyo Standard Time',
+ 'Asia/Tomsk': 'Tomsk Standard Time',
+ 'Asia/Ujung_Pandang': 'Singapore Standard Time',
+ 'Asia/Ulaanbaatar': 'Ulaanbaatar Standard Time',
+ 'Asia/Ulan_Bator': 'Ulaanbaatar Standard Time',
+ 'Asia/Urumqi': 'Central Asia Standard Time',
+ 'Asia/Ust-Nera': 'Vladivostok Standard Time',
+ 'Asia/Vientiane': 'SE Asia Standard Time',
+ 'Asia/Vladivostok': 'Vladivostok Standard Time',
+ 'Asia/Yakutsk': 'Yakutsk Standard Time',
+ 'Asia/Yekaterinburg': 'Ekaterinburg Standard Time',
+ 'Asia/Yerevan': 'Caucasus Standard Time',
+ 'Atlantic/Azores': 'Azores Standard Time',
+ 'Atlantic/Bermuda': 'Atlantic Standard Time',
+ 'Atlantic/Canary': 'GMT Standard Time',
+ 'Atlantic/Cape_Verde': 'Cape Verde Standard Time',
+ 'Atlantic/Faeroe': 'GMT Standard Time',
+ 'Atlantic/Jan_Mayen': 'W. Europe Standard Time',
+ 'Atlantic/Madeira': 'GMT Standard Time',
+ 'Atlantic/Reykjavik': 'Greenwich Standard Time',
+ 'Atlantic/South_Georgia': 'UTC-02',
+ 'Atlantic/St_Helena': 'Greenwich Standard Time',
+ 'Atlantic/Stanley': 'SA Eastern Standard Time',
+ 'Australia/ACT': 'AUS Eastern Standard Time',
+ 'Australia/Adelaide': 'Cen. Australia Standard Time',
+ 'Australia/Brisbane': 'E. Australia Standard Time',
+ 'Australia/Broken_Hill': 'Cen. Australia Standard Time',
+ 'Australia/Canberra': 'AUS Eastern Standard Time',
+ 'Australia/Currie': 'Tasmania Standard Time',
+ 'Australia/Darwin': 'AUS Central Standard Time',
+ 'Australia/Eucla': 'Aus Central W. Standard Time',
+ 'Australia/Hobart': 'Tasmania Standard Time',
+ 'Australia/LHI': 'Lord Howe Standard Time',
+ 'Australia/Lindeman': 'E. Australia Standard Time',
+ 'Australia/Lord_Howe': 'Lord Howe Standard Time',
+ 'Australia/Melbourne': 'AUS Eastern Standard Time',
+ 'Australia/NSW': 'AUS Eastern Standard Time',
+ 'Australia/North': 'AUS Central Standard Time',
+ 'Australia/Perth': 'W. Australia Standard Time',
+ 'Australia/Queensland': 'E. Australia Standard Time',
+ 'Australia/South': 'Cen. Australia Standard Time',
+ 'Australia/Sydney': 'AUS Eastern Standard Time',
+ 'Australia/Tasmania': 'Tasmania Standard Time',
+ 'Australia/Victoria': 'AUS Eastern Standard Time',
+ 'Australia/West': 'W. Australia Standard Time',
+ 'Australia/Yancowinna': 'Cen. Australia Standard Time',
+ 'Brazil/Acre': 'SA Pacific Standard Time',
+ 'Brazil/DeNoronha': 'UTC-02',
+ 'Brazil/East': 'E. South America Standard Time',
+ 'Brazil/West': 'SA Western Standard Time',
+ 'CST6CDT': 'Central Standard Time',
+ 'Canada/Atlantic': 'Atlantic Standard Time',
+ 'Canada/Central': 'Central Standard Time',
+ 'Canada/Eastern': 'Eastern Standard Time',
+ 'Canada/Mountain': 'Mountain Standard Time',
+ 'Canada/Newfoundland': 'Newfoundland Standard Time',
+ 'Canada/Pacific': 'Pacific Standard Time',
+ 'Canada/Saskatchewan': 'Canada Central Standard Time',
+ 'Canada/Yukon': 'Pacific Standard Time',
+ 'Chile/Continental': 'Pacific SA Standard Time',
+ 'Chile/EasterIsland': 'Easter Island Standard Time',
+ 'Cuba': 'Cuba Standard Time',
+ 'EST5EDT': 'Eastern Standard Time',
+ 'Egypt': 'Egypt Standard Time',
+ 'Eire': 'GMT Standard Time',
+ 'Etc/GMT': 'UTC',
+ 'Etc/GMT+1': 'Cape Verde Standard Time',
+ 'Etc/GMT+10': 'Hawaiian Standard Time',
+ 'Etc/GMT+11': 'UTC-11',
+ 'Etc/GMT+12': 'Dateline Standard Time',
+ 'Etc/GMT+2': 'UTC-02',
+ 'Etc/GMT+3': 'SA Eastern Standard Time',
+ 'Etc/GMT+4': 'SA Western Standard Time',
+ 'Etc/GMT+5': 'SA Pacific Standard Time',
+ 'Etc/GMT+6': 'Central America Standard Time',
+ 'Etc/GMT+7': 'US Mountain Standard Time',
+ 'Etc/GMT+8': 'UTC-08',
+ 'Etc/GMT+9': 'UTC-09',
+ 'Etc/GMT-1': 'W. Central Africa Standard Time',
+ 'Etc/GMT-10': 'West Pacific Standard Time',
+ 'Etc/GMT-11': 'Central Pacific Standard Time',
+ 'Etc/GMT-12': 'UTC+12',
+ 'Etc/GMT-13': 'UTC+13',
+ 'Etc/GMT-14': 'Line Islands Standard Time',
+ 'Etc/GMT-2': 'South Africa Standard Time',
+ 'Etc/GMT-3': 'E. Africa Standard Time',
+ 'Etc/GMT-4': 'Arabian Standard Time',
+ 'Etc/GMT-5': 'West Asia Standard Time',
+ 'Etc/GMT-6': 'Central Asia 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',
+ 'Europe/Astrakhan': 'Astrakhan Standard Time',
+ 'Europe/Athens': 'GTB Standard Time',
+ 'Europe/Belfast': 'GMT Standard Time',
+ 'Europe/Belgrade': 'Central Europe Standard Time',
+ 'Europe/Berlin': 'W. Europe Standard Time',
+ 'Europe/Bratislava': 'Central Europe Standard Time',
+ 'Europe/Brussels': 'Romance Standard Time',
+ 'Europe/Bucharest': 'GTB Standard Time',
+ 'Europe/Budapest': 'Central Europe Standard Time',
+ 'Europe/Busingen': 'W. Europe Standard Time',
+ 'Europe/Chisinau': 'E. Europe Standard Time',
+ 'Europe/Copenhagen': 'Romance Standard Time',
+ 'Europe/Dublin': 'GMT Standard Time',
+ 'Europe/Gibraltar': 'W. Europe Standard Time',
+ 'Europe/Guernsey': 'GMT Standard Time',
+ 'Europe/Helsinki': 'FLE Standard Time',
+ 'Europe/Isle_of_Man': 'GMT Standard Time',
+ 'Europe/Istanbul': 'Turkey Standard Time',
+ 'Europe/Jersey': 'GMT Standard Time',
+ 'Europe/Kaliningrad': 'Kaliningrad Standard Time',
+ 'Europe/Kiev': 'FLE Standard Time',
+ 'Europe/Kirov': 'Russian Standard Time',
+ 'Europe/Lisbon': 'GMT Standard Time',
+ 'Europe/Ljubljana': 'Central Europe Standard Time',
+ 'Europe/London': 'GMT Standard Time',
+ 'Europe/Luxembourg': 'W. Europe Standard Time',
+ 'Europe/Madrid': 'Romance Standard Time',
+ 'Europe/Malta': 'W. Europe Standard Time',
+ 'Europe/Mariehamn': 'FLE Standard Time',
+ 'Europe/Minsk': 'Belarus Standard Time',
+ 'Europe/Monaco': 'W. Europe Standard Time',
+ 'Europe/Moscow': 'Russian Standard Time',
+ 'Europe/Oslo': 'W. Europe Standard Time',
+ 'Europe/Paris': 'Romance Standard Time',
+ 'Europe/Podgorica': 'Central Europe Standard Time',
+ 'Europe/Prague': 'Central Europe Standard Time',
+ 'Europe/Riga': 'FLE Standard Time',
+ 'Europe/Rome': 'W. Europe Standard Time',
+ 'Europe/Samara': 'Russia Time Zone 3',
+ 'Europe/San_Marino': 'W. Europe Standard Time',
+ 'Europe/Sarajevo': 'Central European Standard Time',
+ 'Europe/Saratov': 'Saratov Standard Time',
+ 'Europe/Simferopol': 'Russian Standard Time',
+ 'Europe/Skopje': 'Central European Standard Time',
+ 'Europe/Sofia': 'FLE Standard Time',
+ 'Europe/Stockholm': 'W. Europe Standard Time',
+ 'Europe/Tallinn': 'FLE Standard Time',
+ 'Europe/Tirane': 'Central Europe Standard Time',
+ 'Europe/Tiraspol': 'E. Europe Standard Time',
+ 'Europe/Ulyanovsk': 'Astrakhan Standard Time',
+ 'Europe/Uzhgorod': 'FLE Standard Time',
+ 'Europe/Vaduz': 'W. Europe Standard Time',
+ 'Europe/Vatican': 'W. Europe Standard Time',
+ 'Europe/Vienna': 'W. Europe Standard Time',
+ 'Europe/Vilnius': 'FLE Standard Time',
+ 'Europe/Volgograd': 'Volgograd Standard Time',
+ 'Europe/Warsaw': 'Central European Standard Time',
+ 'Europe/Zagreb': 'Central European Standard Time',
+ 'Europe/Zaporozhye': 'FLE Standard Time',
+ 'Europe/Zurich': 'W. Europe Standard Time',
+ 'GB': 'GMT Standard Time',
+ 'GB-Eire': 'GMT Standard Time',
+ 'GMT+0': 'UTC',
+ 'GMT-0': 'UTC',
+ 'GMT0': 'UTC',
+ 'Greenwich': 'UTC',
+ 'Hongkong': 'China Standard Time',
+ 'Iceland': 'Greenwich Standard Time',
+ 'Indian/Antananarivo': 'E. Africa Standard Time',
+ 'Indian/Chagos': 'Central Asia Standard Time',
+ 'Indian/Christmas': 'SE Asia Standard Time',
+ 'Indian/Cocos': 'Myanmar Standard Time',
+ 'Indian/Comoro': 'E. Africa Standard Time',
+ 'Indian/Kerguelen': 'West Asia Standard Time',
+ 'Indian/Mahe': 'Mauritius Standard Time',
+ 'Indian/Maldives': 'West Asia Standard Time',
+ 'Indian/Mauritius': 'Mauritius Standard Time',
+ 'Indian/Mayotte': 'E. Africa Standard Time',
+ 'Indian/Reunion': 'Mauritius Standard Time',
+ 'Iran': 'Iran Standard Time',
+ 'Israel': 'Israel Standard Time',
+ 'Jamaica': 'SA Pacific Standard Time',
+ 'Japan': 'Tokyo Standard Time',
+ 'Kwajalein': 'UTC+12',
+ 'Libya': 'Libya Standard Time',
+ 'MST7MDT': 'Mountain Standard Time',
+ 'Mexico/BajaNorte': 'Pacific Standard Time (Mexico)',
+ 'Mexico/BajaSur': 'Mountain Standard Time (Mexico)',
+ 'Mexico/General': 'Central Standard Time (Mexico)',
+ 'NZ': 'New Zealand Standard Time',
+ 'NZ-CHAT': 'Chatham Islands Standard Time',
+ 'Navajo': 'Mountain Standard Time',
+ 'PRC': 'China Standard Time',
+ 'PST8PDT': 'Pacific Standard Time',
+ 'Pacific/Apia': 'Samoa Standard Time',
+ 'Pacific/Auckland': 'New Zealand Standard Time',
+ 'Pacific/Bougainville': 'Bougainville Standard Time',
+ 'Pacific/Chatham': 'Chatham Islands Standard Time',
+ 'Pacific/Easter': 'Easter Island Standard Time',
+ 'Pacific/Efate': 'Central Pacific Standard Time',
+ 'Pacific/Enderbury': 'UTC+13',
+ 'Pacific/Fakaofo': 'UTC+13',
+ 'Pacific/Fiji': 'Fiji Standard Time',
+ 'Pacific/Funafuti': 'UTC+12',
+ 'Pacific/Galapagos': 'Central America Standard Time',
+ 'Pacific/Gambier': 'UTC-09',
+ 'Pacific/Guadalcanal': 'Central Pacific Standard Time',
+ 'Pacific/Guam': 'West Pacific Standard Time',
+ 'Pacific/Honolulu': 'Hawaiian Standard Time',
+ 'Pacific/Johnston': 'Hawaiian Standard Time',
+ 'Pacific/Kiritimati': 'Line Islands Standard Time',
+ 'Pacific/Kosrae': 'Central Pacific Standard Time',
+ 'Pacific/Kwajalein': 'UTC+12',
+ 'Pacific/Majuro': 'UTC+12',
+ 'Pacific/Marquesas': 'Marquesas Standard Time',
+ 'Pacific/Midway': 'UTC-11',
+ 'Pacific/Nauru': 'UTC+12',
+ 'Pacific/Niue': 'UTC-11',
+ 'Pacific/Norfolk': 'Norfolk Standard Time',
+ 'Pacific/Noumea': 'Central Pacific Standard Time',
+ 'Pacific/Pago_Pago': 'UTC-11',
+ 'Pacific/Palau': 'Tokyo Standard Time',
+ 'Pacific/Pitcairn': 'UTC-08',
+ 'Pacific/Ponape': 'Central Pacific Standard Time',
+ 'Pacific/Port_Moresby': 'West Pacific Standard Time',
+ 'Pacific/Rarotonga': 'Hawaiian Standard Time',
+ 'Pacific/Saipan': 'West Pacific Standard Time',
+ 'Pacific/Samoa': 'UTC-11',
+ 'Pacific/Tahiti': 'Hawaiian Standard Time',
+ 'Pacific/Tarawa': 'UTC+12',
+ 'Pacific/Tongatapu': 'Tonga Standard Time',
+ 'Pacific/Truk': 'West Pacific Standard Time',
+ 'Pacific/Wake': 'UTC+12',
+ 'Pacific/Wallis': 'UTC+12',
+ 'Poland': 'Central European Standard Time',
+ 'Portugal': 'GMT Standard Time',
+ 'ROC': 'Taipei 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',
+ 'US/Central': 'Central Standard Time',
+ 'US/Eastern': 'Eastern Standard Time',
+ 'US/Hawaii': 'Hawaiian Standard Time',
+ 'US/Indiana-Starke': 'Central Standard Time',
+ 'US/Michigan': 'Eastern Standard Time',
+ 'US/Mountain': 'Mountain Standard Time',
+ 'US/Pacific': 'Pacific Standard Time',
+ 'US/Samoa': 'UTC-11',
+ 'UTC': 'UTC',
+ 'Universal': 'UTC',
+ 'W-SU': 'Russian Standard Time',
+ 'Zulu': 'UTC'}
diff --git a/contrib/python/tzlocal/py2/ya.make b/contrib/python/tzlocal/py2/ya.make
new file mode 100644
index 0000000000..bb647f9e4b
--- /dev/null
+++ b/contrib/python/tzlocal/py2/ya.make
@@ -0,0 +1,34 @@
+# Generated by devtools/yamaker (pypi).
+
+PY2_LIBRARY()
+
+VERSION(2.1)
+
+LICENSE(MIT)
+
+PEERDIR(
+ contrib/python/pytz
+)
+
+NO_LINT()
+
+NO_CHECK_IMPORTS(
+ tzlocal.win32
+)
+
+PY_SRCS(
+ TOP_LEVEL
+ tzlocal/__init__.py
+ tzlocal/unix.py
+ tzlocal/utils.py
+ tzlocal/win32.py
+ tzlocal/windows_tz.py
+)
+
+RESOURCE_FILES(
+ PREFIX contrib/python/tzlocal/py2/
+ .dist-info/METADATA
+ .dist-info/top_level.txt
+)
+
+END()
diff --git a/contrib/python/tzlocal/py3/.dist-info/METADATA b/contrib/python/tzlocal/py3/.dist-info/METADATA
new file mode 100644
index 0000000000..c41851c9f8
--- /dev/null
+++ b/contrib/python/tzlocal/py3/.dist-info/METADATA
@@ -0,0 +1,248 @@
+Metadata-Version: 2.1
+Name: tzlocal
+Version: 5.2
+Summary: tzinfo object for the local timezone
+Author-email: Lennart Regebro <regebro@gmail.com>
+License: MIT
+Project-URL: Source code, https://github.com/regebro/tzlocal
+Project-URL: Changelog, https://github.com/regebro/tzlocal/blob/master/CHANGES.txt
+Project-URL: Issue tracker, https://github.com/regebro/tzlocal/issues
+Keywords: timezone
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Operating System :: Microsoft :: Windows
+Classifier: Operating System :: Unix
+Classifier: Operating System :: MacOS :: MacOS X
+Classifier: Typing :: Typed
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
+Requires-Python: >=3.8
+Description-Content-Type: text/x-rst
+License-File: LICENSE.txt
+Requires-Dist: tzdata ; platform_system == "Windows"
+Requires-Dist: backports.zoneinfo ; python_version < "3.9"
+Provides-Extra: devenv
+Requires-Dist: pytest (>=4.3) ; extra == 'devenv'
+Requires-Dist: pytest-mock (>=3.3) ; extra == 'devenv'
+Requires-Dist: pytest-cov ; extra == 'devenv'
+Requires-Dist: check-manifest ; extra == 'devenv'
+Requires-Dist: zest.releaser ; extra == 'devenv'
+
+tzlocal
+=======
+
+API CHANGE!
+-----------
+
+With version 3.0 of tzlocal, tzlocal no longer returned `pytz` objects, but
+`zoneinfo` objects, which has a different API. Since 4.0, it now restored
+partial compatibility for `pytz` users through Paul Ganssle's
+`pytz_deprecation_shim`.
+
+tzlocal 4.0 also adds an official function `get_localzone_name()` to get only
+the timezone name, instead of a timezone object. On unix, it can raise an
+error if you don't have a timezone name configured, where `get_localzone()`
+will succeed, so only use that if you need the timezone name.
+
+4.0 also adds way more information on what is going wrong in your
+configuration when the configuration files are unclear or contradictory.
+
+Version 5.0 removes the `pytz_deprecation_shim`, and now only returns
+`zoneinfo` objects, like verion 3.0 did. If you need `pytz` objects, you have
+to stay on version 4.0. If there are bugs in version 4.0, I will release
+updates, but there will be no further functional changes on the 4.x branch.
+
+
+Info
+----
+
+This Python module returns the `IANA time zone name
+<https://www.iana.org/time-zones>`_ for your local time zone or a ``tzinfo``
+object with the local timezone information, under Unix and Windows.
+
+It requires Python 3.8 or later, and will use the ``backports.tzinfo``
+package, for Python 3.8.
+
+This module attempts to fix a glaring hole in the ``pytz`` and ``zoneinfo``
+modules, that there is no way to get the local timezone information, unless
+you know the zoneinfo name, and under several Linux distros that's hard or
+impossible to figure out.
+
+With ``tzlocal`` you only need to call ``get_localzone()`` and you will get a
+``tzinfo`` object with the local time zone info. On some Unices you will
+still not get to know what the timezone name is, but you don't need that when
+you have the tzinfo file. However, if the timezone name is readily available
+it will be used.
+
+What it's not for
+-----------------
+
+It's not for converting the current time between UTC and your local time. There are
+other, simpler ways of doing this. This is ig you need to know things like the name
+of the time zone, or if you need to be able to convert between your time zone and
+another time zone for times that are in the future or in the past.
+
+For current time conversions to and from UTC, look in the Python ``time`` module.
+
+
+Supported systems
+-----------------
+
+These are the systems that are in theory supported:
+
+ * Windows 2000 and later
+
+ * Any unix-like system with a ``/etc/localtime`` or ``/usr/local/etc/localtime``
+
+If you have one of the above systems and it does not work, it's a bug.
+Please report it.
+
+Please note that if you are getting a time zone called ``local``, this is not
+a bug, it's actually the main feature of ``tzlocal``, that even if your
+system does NOT have a configuration file with the zoneinfo name of your time
+zone, it will still work.
+
+You can also use ``tzlocal`` to get the name of your local timezone, but only
+if your system is configured to make that possible. ``tzlocal`` looks for the
+timezone name in ``/etc/timezone``, ``/var/db/zoneinfo``,
+``/etc/sysconfig/clock`` and ``/etc/conf.d/clock``. If your
+``/etc/localtime`` is a symlink it can also extract the name from that
+symlink.
+
+If you need the name of your local time zone, then please make sure your
+system is properly configured to allow that.
+
+If your unix system doesn't have a timezone configured, tzlocal will default
+to UTC.
+
+Notes on Docker
+---------------
+
+It turns out that Docker images frequently have broken timezone setups.
+This usually resuts in a warning that the configuration is wrong, or that
+the timezone offset doesn't match the found timezone.
+
+The easiest way to fix that is to set a TZ variable in your docker setup
+to whatever timezone you want, which is usually the timezone your host
+computer has.
+
+Usage
+-----
+
+Load the local timezone:
+
+ >>> from tzlocal import get_localzone
+ >>> tz = get_localzone()
+ >>> tz
+ zoneinfo.ZoneInfo(key='Europe/Warsaw')
+
+Create a local datetime:
+
+ >>> from datetime import datetime
+ >>> dt = datetime(2015, 4, 10, 7, 22, tzinfo=tz)
+ >>> dt
+ datetime.datetime(2015, 4, 10, 7, 22, tzinfo=zoneinfo.ZoneInfo(key='Europe/Warsaw'))
+
+Lookup another timezone with ``zoneinfo`` (``backports.zoneinfo`` on Python 3.8 or earlier):
+
+ >>> from zoneinfo import ZoneInfo
+ >>> eastern = ZoneInfo('US/Eastern')
+
+Convert the datetime:
+
+ >>> dt.astimezone(eastern)
+ datetime.datetime(2015, 4, 10, 1, 22, tzinfo=zoneinfo.ZoneInfo(key='US/Eastern'))
+
+If you just want the name of the local timezone, use `get_localzone_name()`:
+
+ >>> from tzlocal import get_localzone_name
+ >>> get_localzone_name()
+ "Europe/Warsaw"
+
+Please note that under Unix, `get_localzone_name()` may fail if there is no zone
+configured, where `get_localzone()` would generally succeed.
+
+Troubleshooting
+---------------
+
+If you don't get the result you expect, try running it with debugging turned on.
+Start a python interpreter that has tzlocal installed, and run the following code::
+
+ import logging
+ logging.basicConfig(level="DEBUG")
+ import tzlocal
+ tzlocal.get_localzone()
+
+The output should look something like this, and this will tell you what
+configurations were found::
+
+ DEBUG:root:/etc/timezone found, contents:
+ Europe/Warsaw
+
+ DEBUG:root:/etc/localtime found
+ DEBUG:root:2 found:
+ {'/etc/timezone': 'Europe/Warsaw', '/etc/localtime is a symlink to': 'Europe/Warsaw'}
+ zoneinfo.ZoneInfo(key='Europe/Warsaw')
+
+
+Development
+-----------
+
+For ease of development, there is a Makefile that will help you with basic tasks,
+like creating a development environment with all the necessary tools (although
+you need a supported Python version installed first)::
+
+ $ make devenv
+
+To run tests::
+
+ $ make test
+
+Check the syntax::
+
+ $ make check
+
+
+Maintainer
+----------
+
+* Lennart Regebro, regebro@gmail.com
+
+Contributors
+------------
+
+* Marc Van Olmen
+* Benjamen Meyer
+* Manuel Ebert
+* Xiaokun Zhu
+* Cameris
+* Edward Betts
+* McK KIM
+* Cris Ewing
+* Ayala Shachar
+* Lev Maximov
+* Jakub Wilk
+* John Quarles
+* Preston Landers
+* Victor Torres
+* Jean Jordaan
+* Zackary Welch
+* Mickaël Schoentgen
+* Gabriel Corona
+* Alex Grönholm
+* Julin S
+* Miroslav Šedivý
+* revansSZ
+* Sam Treweek
+* Peter Di Pasquale
+* Rongrong
+
+(Sorry if I forgot someone)
+
+License
+-------
+
+* MIT https://opensource.org/licenses/MIT
diff --git a/contrib/python/tzlocal/py3/.dist-info/top_level.txt b/contrib/python/tzlocal/py3/.dist-info/top_level.txt
new file mode 100644
index 0000000000..cd5e9b12a4
--- /dev/null
+++ b/contrib/python/tzlocal/py3/.dist-info/top_level.txt
@@ -0,0 +1 @@
+tzlocal
diff --git a/contrib/python/tzlocal/py3/LICENSE.txt b/contrib/python/tzlocal/py3/LICENSE.txt
new file mode 100644
index 0000000000..9be1d2fe59
--- /dev/null
+++ b/contrib/python/tzlocal/py3/LICENSE.txt
@@ -0,0 +1,19 @@
+Copyright 2011-2017 Lennart Regebro
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/contrib/python/tzlocal/py3/README.rst b/contrib/python/tzlocal/py3/README.rst
new file mode 100644
index 0000000000..3dd27d68c9
--- /dev/null
+++ b/contrib/python/tzlocal/py3/README.rst
@@ -0,0 +1,215 @@
+tzlocal
+=======
+
+API CHANGE!
+-----------
+
+With version 3.0 of tzlocal, tzlocal no longer returned `pytz` objects, but
+`zoneinfo` objects, which has a different API. Since 4.0, it now restored
+partial compatibility for `pytz` users through Paul Ganssle's
+`pytz_deprecation_shim`.
+
+tzlocal 4.0 also adds an official function `get_localzone_name()` to get only
+the timezone name, instead of a timezone object. On unix, it can raise an
+error if you don't have a timezone name configured, where `get_localzone()`
+will succeed, so only use that if you need the timezone name.
+
+4.0 also adds way more information on what is going wrong in your
+configuration when the configuration files are unclear or contradictory.
+
+Version 5.0 removes the `pytz_deprecation_shim`, and now only returns
+`zoneinfo` objects, like verion 3.0 did. If you need `pytz` objects, you have
+to stay on version 4.0. If there are bugs in version 4.0, I will release
+updates, but there will be no further functional changes on the 4.x branch.
+
+
+Info
+----
+
+This Python module returns the `IANA time zone name
+<https://www.iana.org/time-zones>`_ for your local time zone or a ``tzinfo``
+object with the local timezone information, under Unix and Windows.
+
+It requires Python 3.8 or later, and will use the ``backports.tzinfo``
+package, for Python 3.8.
+
+This module attempts to fix a glaring hole in the ``pytz`` and ``zoneinfo``
+modules, that there is no way to get the local timezone information, unless
+you know the zoneinfo name, and under several Linux distros that's hard or
+impossible to figure out.
+
+With ``tzlocal`` you only need to call ``get_localzone()`` and you will get a
+``tzinfo`` object with the local time zone info. On some Unices you will
+still not get to know what the timezone name is, but you don't need that when
+you have the tzinfo file. However, if the timezone name is readily available
+it will be used.
+
+What it's not for
+-----------------
+
+It's not for converting the current time between UTC and your local time. There are
+other, simpler ways of doing this. This is ig you need to know things like the name
+of the time zone, or if you need to be able to convert between your time zone and
+another time zone for times that are in the future or in the past.
+
+For current time conversions to and from UTC, look in the Python ``time`` module.
+
+
+Supported systems
+-----------------
+
+These are the systems that are in theory supported:
+
+ * Windows 2000 and later
+
+ * Any unix-like system with a ``/etc/localtime`` or ``/usr/local/etc/localtime``
+
+If you have one of the above systems and it does not work, it's a bug.
+Please report it.
+
+Please note that if you are getting a time zone called ``local``, this is not
+a bug, it's actually the main feature of ``tzlocal``, that even if your
+system does NOT have a configuration file with the zoneinfo name of your time
+zone, it will still work.
+
+You can also use ``tzlocal`` to get the name of your local timezone, but only
+if your system is configured to make that possible. ``tzlocal`` looks for the
+timezone name in ``/etc/timezone``, ``/var/db/zoneinfo``,
+``/etc/sysconfig/clock`` and ``/etc/conf.d/clock``. If your
+``/etc/localtime`` is a symlink it can also extract the name from that
+symlink.
+
+If you need the name of your local time zone, then please make sure your
+system is properly configured to allow that.
+
+If your unix system doesn't have a timezone configured, tzlocal will default
+to UTC.
+
+Notes on Docker
+---------------
+
+It turns out that Docker images frequently have broken timezone setups.
+This usually resuts in a warning that the configuration is wrong, or that
+the timezone offset doesn't match the found timezone.
+
+The easiest way to fix that is to set a TZ variable in your docker setup
+to whatever timezone you want, which is usually the timezone your host
+computer has.
+
+Usage
+-----
+
+Load the local timezone:
+
+ >>> from tzlocal import get_localzone
+ >>> tz = get_localzone()
+ >>> tz
+ zoneinfo.ZoneInfo(key='Europe/Warsaw')
+
+Create a local datetime:
+
+ >>> from datetime import datetime
+ >>> dt = datetime(2015, 4, 10, 7, 22, tzinfo=tz)
+ >>> dt
+ datetime.datetime(2015, 4, 10, 7, 22, tzinfo=zoneinfo.ZoneInfo(key='Europe/Warsaw'))
+
+Lookup another timezone with ``zoneinfo`` (``backports.zoneinfo`` on Python 3.8 or earlier):
+
+ >>> from zoneinfo import ZoneInfo
+ >>> eastern = ZoneInfo('US/Eastern')
+
+Convert the datetime:
+
+ >>> dt.astimezone(eastern)
+ datetime.datetime(2015, 4, 10, 1, 22, tzinfo=zoneinfo.ZoneInfo(key='US/Eastern'))
+
+If you just want the name of the local timezone, use `get_localzone_name()`:
+
+ >>> from tzlocal import get_localzone_name
+ >>> get_localzone_name()
+ "Europe/Warsaw"
+
+Please note that under Unix, `get_localzone_name()` may fail if there is no zone
+configured, where `get_localzone()` would generally succeed.
+
+Troubleshooting
+---------------
+
+If you don't get the result you expect, try running it with debugging turned on.
+Start a python interpreter that has tzlocal installed, and run the following code::
+
+ import logging
+ logging.basicConfig(level="DEBUG")
+ import tzlocal
+ tzlocal.get_localzone()
+
+The output should look something like this, and this will tell you what
+configurations were found::
+
+ DEBUG:root:/etc/timezone found, contents:
+ Europe/Warsaw
+
+ DEBUG:root:/etc/localtime found
+ DEBUG:root:2 found:
+ {'/etc/timezone': 'Europe/Warsaw', '/etc/localtime is a symlink to': 'Europe/Warsaw'}
+ zoneinfo.ZoneInfo(key='Europe/Warsaw')
+
+
+Development
+-----------
+
+For ease of development, there is a Makefile that will help you with basic tasks,
+like creating a development environment with all the necessary tools (although
+you need a supported Python version installed first)::
+
+ $ make devenv
+
+To run tests::
+
+ $ make test
+
+Check the syntax::
+
+ $ make check
+
+
+Maintainer
+----------
+
+* Lennart Regebro, regebro@gmail.com
+
+Contributors
+------------
+
+* Marc Van Olmen
+* Benjamen Meyer
+* Manuel Ebert
+* Xiaokun Zhu
+* Cameris
+* Edward Betts
+* McK KIM
+* Cris Ewing
+* Ayala Shachar
+* Lev Maximov
+* Jakub Wilk
+* John Quarles
+* Preston Landers
+* Victor Torres
+* Jean Jordaan
+* Zackary Welch
+* Mickaël Schoentgen
+* Gabriel Corona
+* Alex Grönholm
+* Julin S
+* Miroslav Šedivý
+* revansSZ
+* Sam Treweek
+* Peter Di Pasquale
+* Rongrong
+
+(Sorry if I forgot someone)
+
+License
+-------
+
+* MIT https://opensource.org/licenses/MIT
diff --git a/contrib/python/tzlocal/py3/tzlocal/__init__.py b/contrib/python/tzlocal/py3/tzlocal/__init__.py
new file mode 100644
index 0000000000..8296a15dc4
--- /dev/null
+++ b/contrib/python/tzlocal/py3/tzlocal/__init__.py
@@ -0,0 +1,19 @@
+import sys
+
+if sys.platform == "win32":
+ from tzlocal.win32 import (
+ get_localzone,
+ get_localzone_name,
+ reload_localzone,
+ )
+else:
+ from tzlocal.unix import get_localzone, get_localzone_name, reload_localzone
+
+from tzlocal.utils import assert_tz_offset
+
+__all__ = [
+ "get_localzone",
+ "get_localzone_name",
+ "reload_localzone",
+ "assert_tz_offset",
+]
diff --git a/contrib/python/tzlocal/py3/tzlocal/py.typed b/contrib/python/tzlocal/py3/tzlocal/py.typed
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/contrib/python/tzlocal/py3/tzlocal/py.typed
diff --git a/contrib/python/tzlocal/py3/tzlocal/unix.py b/contrib/python/tzlocal/py3/tzlocal/unix.py
new file mode 100644
index 0000000000..117c18d373
--- /dev/null
+++ b/contrib/python/tzlocal/py3/tzlocal/unix.py
@@ -0,0 +1,231 @@
+import logging
+import os
+import re
+import sys
+import warnings
+from datetime import timezone
+
+from tzlocal import utils
+
+if sys.version_info >= (3, 9):
+ import zoneinfo # pragma: no cover
+else:
+ from backports import zoneinfo # pragma: no cover
+
+_cache_tz = None
+_cache_tz_name = None
+
+log = logging.getLogger("tzlocal")
+
+
+def _get_localzone_name(_root="/"):
+ """Tries to find the local timezone configuration.
+
+ 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."""
+
+ # 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(os.path.join(_root, "system/bin/getprop")):
+ log.debug("This looks like Termux")
+
+ import subprocess
+
+ try:
+ androidtz = (
+ subprocess.check_output(["getprop", "persist.sys.timezone"])
+ .strip()
+ .decode()
+ )
+ return androidtz
+ except (OSError, subprocess.CalledProcessError):
+ # proot environment or failed to getprop
+ log.debug("It's not termux?")
+ pass
+
+ # Now look for distribution specific configuration files
+ # that contain the timezone name.
+
+ # 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) as tzfile:
+ data = tzfile.read()
+ log.debug(f"{tzpath} found, contents:\n {data}")
+
+ etctz = data.strip("/ \t\r\n")
+ if not etctz:
+ # Empty file, skip
+ continue
+ 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 not etctz:
+ continue
+
+ found_configs[tzpath] = etctz.replace(" ", "_")
+
+ except (OSError, 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,
+ # 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(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)
+ try:
+ with open(tzpath, "rt") as tzfile:
+ data = tzfile.readlines()
+ log.debug(f"{tzpath} found, contents:\n {data}")
+
+ 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
+ found_configs[tzpath] = etctz.replace(" ", "_")
+
+ except (OSError, 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")
+ if os.path.exists(tzpath) and os.path.islink(tzpath):
+ log.debug(f"{tzpath} found")
+ etctz = os.path.realpath(tzpath)
+ start = etctz.find("/") + 1
+ while start != 0:
+ etctz = etctz[start:]
+ try:
+ zoneinfo.ZoneInfo(etctz)
+ tzinfo = f"{tzpath} is a symlink to"
+ found_configs[tzinfo] = etctz.replace(" ", "_")
+ # Only need first valid relative path in simlink.
+ break
+ except zoneinfo.ZoneInfoNotFoundError:
+ pass
+ start = etctz.find("/") + 1
+
+ if len(found_configs) > 0:
+ log.debug(f"{len(found_configs)} found:\n {found_configs}")
+ # We found some explicit config of some sort!
+ if len(found_configs) > 1:
+ # Uh-oh, multiple configs. See if they match:
+ unique_tzs = set()
+ zoneinfopath = os.path.join(_root, "usr", "share", "zoneinfo")
+ directory_depth = len(zoneinfopath.split(os.path.sep))
+
+ 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(zoneinfopath, *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 zoneinfo.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
+ log.debug("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 = zoneinfo.ZoneInfo.from_file(tzfile, key="local")
+ break
+ else:
+ warnings.warn("Can not find any timezone configuration, defaulting to UTC.")
+ tz = timezone.utc
+ else:
+ tz = zoneinfo.ZoneInfo(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, error=False)
+ return tz
+
+
+def get_localzone_name() -> str:
+ """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
+
+
+def get_localzone() -> zoneinfo.ZoneInfo:
+ """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() -> zoneinfo.ZoneInfo:
+ """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
diff --git a/contrib/python/tzlocal/py3/tzlocal/utils.py b/contrib/python/tzlocal/py3/tzlocal/utils.py
new file mode 100644
index 0000000000..3990535f17
--- /dev/null
+++ b/contrib/python/tzlocal/py3/tzlocal/utils.py
@@ -0,0 +1,112 @@
+import calendar
+import datetime
+import logging
+import os
+import time
+import warnings
+
+try:
+ import zoneinfo # pragma: no cover
+except ImportError:
+ from backports import zoneinfo # pragma: no cover
+
+from tzlocal import windows_tz
+
+log = logging.getLogger("tzlocal")
+
+
+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, error=True):
+ """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.
+
+ If error is True, this method will raise a ValueError, otherwise it will
+ emit a warning.
+ """
+
+ tz_offset = get_tz_offset(tz)
+ system_offset = calendar.timegm(time.localtime()) - calendar.timegm(time.gmtime())
+ # No one has timezone offsets less than a minute, so this should be close enough:
+ if abs(tz_offset - system_offset) > 60:
+ msg = (
+ f"Timezone offset does not match system offset: {tz_offset} != {system_offset}. "
+ "Please, check your config files."
+ )
+ if error:
+ raise ValueError(msg)
+ warnings.warn(msg)
+
+
+def _tz_name_from_env(tzenv=None):
+ if tzenv is None:
+ tzenv = os.environ.get("TZ")
+
+ if not tzenv:
+ return None
+
+ log.debug(f"Found a TZ environment: {tzenv}")
+
+ 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]
+
+ log.debug("TZ does not contain a time zone name")
+ return None
+
+
+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:
+ return zoneinfo.ZoneInfo.from_file(tzfile, key=tzname)
+
+ # TZ must specify a zoneinfo zone.
+ try:
+ tz = zoneinfo.ZoneInfo(tzenv)
+ # That worked, so we return this:
+ return tz
+ except zoneinfo.ZoneInfoNotFoundError:
+ # Nope, it's something like "PST4DST" etc, we can't handle that.
+ raise zoneinfo.ZoneInfoNotFoundError(
+ f"tzlocal() does not support non-zoneinfo timezones like {tzenv}. \n"
+ "Please use a timezone in the form of Continent/City"
+ ) from None
diff --git a/contrib/python/tzlocal/py3/tzlocal/win32.py b/contrib/python/tzlocal/py3/tzlocal/win32.py
new file mode 100644
index 0000000000..2fa59fe6ca
--- /dev/null
+++ b/contrib/python/tzlocal/py3/tzlocal/win32.py
@@ -0,0 +1,147 @@
+import logging
+from datetime import datetime
+
+try:
+ import _winreg as winreg
+except ImportError:
+ import winreg
+
+try:
+ import zoneinfo # pragma: no cover
+except ImportError:
+ from backports import zoneinfo # pragma: no cover
+
+from tzlocal import utils
+from tzlocal.windows_tz import win_tz
+
+_cache_tz = None
+_cache_tz_name = None
+
+log = logging.getLogger("tzlocal")
+
+
+def valuestodict(key):
+ """Convert a registry key's values to a dictionary."""
+ result = {}
+ size = winreg.QueryInfoKey(key)[1]
+ for i in range(size):
+ data = winreg.EnumValue(key, i)
+ result[data[0]] = data[1]
+ return result
+
+
+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
+
+ log.debug("Looking up time zone info from registry")
+ handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
+
+ TZLOCALKEYNAME = r"SYSTEM\CurrentControlSet\Control\TimeZoneInformation"
+ localtz = winreg.OpenKey(handle, TZLOCALKEYNAME)
+ keyvalues = valuestodict(localtz)
+ localtz.Close()
+
+ 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]
+ else:
+ # Don't support XP any longer
+ raise LookupError("Can not find Windows timezone configuration")
+
+ timezone = win_tz.get(tzkeyname)
+ if timezone is None:
+ # Nope, that didn't work. Try adding "Standard Time",
+ # it seems to work a lot of times:
+ timezone = win_tz.get(tzkeyname + " Standard Time")
+
+ # Return what we have.
+ if timezone is None:
+ raise zoneinfo.ZoneInfoNotFoundError(tzkeyname)
+
+ if keyvalues.get("DynamicDaylightTimeDisabled", 0) == 1:
+ # DST is disabled, so don't return the timezone name,
+ # instead return Etc/GMT+offset
+
+ tz = zoneinfo.ZoneInfo(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 zoneinfo.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 zoneinfo.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() -> str:
+ """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() -> zoneinfo.ZoneInfo:
+ """Returns the zoneinfo-based tzinfo object that matches the Windows-configured timezone."""
+
+ global _cache_tz
+ if _cache_tz is None:
+ _cache_tz = zoneinfo.ZoneInfo(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, error=False)
+
+ return _cache_tz
+
+
+def reload_localzone() -> zoneinfo.ZoneInfo:
+ """Reload the cached localzone. You need to call this if the timezone has changed."""
+ global _cache_tz
+ global _cache_tz_name
+ _cache_tz_name = _get_localzone_name()
+ _cache_tz = zoneinfo.ZoneInfo(_cache_tz_name)
+ utils.assert_tz_offset(_cache_tz, error=False)
+ return _cache_tz
diff --git a/contrib/python/tzlocal/py3/tzlocal/windows_tz.py b/contrib/python/tzlocal/py3/tzlocal/windows_tz.py
new file mode 100644
index 0000000000..3d47576086
--- /dev/null
+++ b/contrib/python/tzlocal/py3/tzlocal/windows_tz.py
@@ -0,0 +1,736 @@
+# This file is autogenerated by the update_windows_mapping.py script
+# Do not edit.
+win_tz = {
+ "AUS Central Standard Time": "Australia/Darwin",
+ "AUS Eastern Standard Time": "Australia/Sydney",
+ "Afghanistan Standard Time": "Asia/Kabul",
+ "Alaskan Standard Time": "America/Anchorage",
+ "Aleutian Standard Time": "America/Adak",
+ "Altai Standard Time": "Asia/Barnaul",
+ "Arab Standard Time": "Asia/Riyadh",
+ "Arabian Standard Time": "Asia/Dubai",
+ "Arabic Standard Time": "Asia/Baghdad",
+ "Argentina Standard Time": "America/Buenos_Aires",
+ "Astrakhan Standard Time": "Europe/Astrakhan",
+ "Atlantic Standard Time": "America/Halifax",
+ "Aus Central W. Standard Time": "Australia/Eucla",
+ "Azerbaijan Standard Time": "Asia/Baku",
+ "Azores Standard Time": "Atlantic/Azores",
+ "Bahia Standard Time": "America/Bahia",
+ "Bangladesh Standard Time": "Asia/Dhaka",
+ "Belarus Standard Time": "Europe/Minsk",
+ "Bougainville Standard Time": "Pacific/Bougainville",
+ "Canada Central Standard Time": "America/Regina",
+ "Cape Verde Standard Time": "Atlantic/Cape_Verde",
+ "Caucasus Standard Time": "Asia/Yerevan",
+ "Cen. Australia Standard Time": "Australia/Adelaide",
+ "Central America Standard Time": "America/Guatemala",
+ "Central Asia Standard Time": "Asia/Almaty",
+ "Central Brazilian Standard Time": "America/Cuiaba",
+ "Central Europe Standard Time": "Europe/Budapest",
+ "Central European Standard Time": "Europe/Warsaw",
+ "Central Pacific Standard Time": "Pacific/Guadalcanal",
+ "Central Standard Time": "America/Chicago",
+ "Central Standard Time (Mexico)": "America/Mexico_City",
+ "Chatham Islands Standard Time": "Pacific/Chatham",
+ "China Standard Time": "Asia/Shanghai",
+ "Cuba Standard Time": "America/Havana",
+ "Dateline Standard Time": "Etc/GMT+12",
+ "E. Africa Standard Time": "Africa/Nairobi",
+ "E. Australia Standard Time": "Australia/Brisbane",
+ "E. Europe Standard Time": "Europe/Chisinau",
+ "E. South America Standard Time": "America/Sao_Paulo",
+ "Easter Island Standard Time": "Pacific/Easter",
+ "Eastern Standard Time": "America/New_York",
+ "Eastern Standard Time (Mexico)": "America/Cancun",
+ "Egypt Standard Time": "Africa/Cairo",
+ "Ekaterinburg Standard Time": "Asia/Yekaterinburg",
+ "FLE Standard Time": "Europe/Kiev",
+ "Fiji Standard Time": "Pacific/Fiji",
+ "GMT Standard Time": "Europe/London",
+ "GTB Standard Time": "Europe/Bucharest",
+ "Georgian Standard Time": "Asia/Tbilisi",
+ "Greenland Standard Time": "America/Godthab",
+ "Greenwich Standard Time": "Atlantic/Reykjavik",
+ "Haiti Standard Time": "America/Port-au-Prince",
+ "Hawaiian Standard Time": "Pacific/Honolulu",
+ "India Standard Time": "Asia/Calcutta",
+ "Iran Standard Time": "Asia/Tehran",
+ "Israel Standard Time": "Asia/Jerusalem",
+ "Jordan Standard Time": "Asia/Amman",
+ "Kaliningrad Standard Time": "Europe/Kaliningrad",
+ "Korea Standard Time": "Asia/Seoul",
+ "Libya Standard Time": "Africa/Tripoli",
+ "Line Islands Standard Time": "Pacific/Kiritimati",
+ "Lord Howe Standard Time": "Australia/Lord_Howe",
+ "Magadan Standard Time": "Asia/Magadan",
+ "Magallanes Standard Time": "America/Punta_Arenas",
+ "Marquesas Standard Time": "Pacific/Marquesas",
+ "Mauritius Standard Time": "Indian/Mauritius",
+ "Middle East Standard Time": "Asia/Beirut",
+ "Montevideo Standard Time": "America/Montevideo",
+ "Morocco Standard Time": "Africa/Casablanca",
+ "Mountain Standard Time": "America/Denver",
+ "Mountain Standard Time (Mexico)": "America/Mazatlan",
+ "Myanmar Standard Time": "Asia/Rangoon",
+ "N. Central Asia Standard Time": "Asia/Novosibirsk",
+ "Namibia Standard Time": "Africa/Windhoek",
+ "Nepal Standard Time": "Asia/Katmandu",
+ "New Zealand Standard Time": "Pacific/Auckland",
+ "Newfoundland Standard Time": "America/St_Johns",
+ "Norfolk Standard Time": "Pacific/Norfolk",
+ "North Asia East Standard Time": "Asia/Irkutsk",
+ "North Asia Standard Time": "Asia/Krasnoyarsk",
+ "North Korea Standard Time": "Asia/Pyongyang",
+ "Omsk Standard Time": "Asia/Omsk",
+ "Pacific SA Standard Time": "America/Santiago",
+ "Pacific Standard Time": "America/Los_Angeles",
+ "Pacific Standard Time (Mexico)": "America/Tijuana",
+ "Pakistan Standard Time": "Asia/Karachi",
+ "Paraguay Standard Time": "America/Asuncion",
+ "Qyzylorda Standard Time": "Asia/Qyzylorda",
+ "Romance Standard Time": "Europe/Paris",
+ "Russia Time Zone 10": "Asia/Srednekolymsk",
+ "Russia Time Zone 11": "Asia/Kamchatka",
+ "Russia Time Zone 3": "Europe/Samara",
+ "Russian Standard Time": "Europe/Moscow",
+ "SA Eastern Standard Time": "America/Cayenne",
+ "SA Pacific Standard Time": "America/Bogota",
+ "SA Western Standard Time": "America/La_Paz",
+ "SE Asia Standard Time": "Asia/Bangkok",
+ "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",
+ "South Sudan Standard Time": "Africa/Juba",
+ "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",
+ "Tocantins Standard Time": "America/Araguaina",
+ "Tokyo Standard Time": "Asia/Tokyo",
+ "Tomsk Standard Time": "Asia/Tomsk",
+ "Tonga Standard Time": "Pacific/Tongatapu",
+ "Transbaikal Standard Time": "Asia/Chita",
+ "Turkey Standard Time": "Europe/Istanbul",
+ "Turks And Caicos Standard Time": "America/Grand_Turk",
+ "US Eastern Standard Time": "America/Indianapolis",
+ "US Mountain Standard Time": "America/Phoenix",
+ "UTC": "Etc/UTC",
+ "UTC+12": "Etc/GMT-12",
+ "UTC+13": "Etc/GMT-13",
+ "UTC-02": "Etc/GMT+2",
+ "UTC-08": "Etc/GMT+8",
+ "UTC-09": "Etc/GMT+9",
+ "UTC-11": "Etc/GMT+11",
+ "Ulaanbaatar Standard Time": "Asia/Ulaanbaatar",
+ "Venezuela Standard Time": "America/Caracas",
+ "Vladivostok Standard Time": "Asia/Vladivostok",
+ "Volgograd Standard Time": "Europe/Volgograd",
+ "W. Australia Standard Time": "Australia/Perth",
+ "W. Central Africa Standard Time": "Africa/Lagos",
+ "W. Europe Standard Time": "Europe/Berlin",
+ "W. Mongolia Standard Time": "Asia/Hovd",
+ "West Asia Standard Time": "Asia/Tashkent",
+ "West Bank Standard Time": "Asia/Hebron",
+ "West Pacific Standard Time": "Pacific/Port_Moresby",
+ "Yakutsk Standard Time": "Asia/Yakutsk",
+ "Yukon Standard Time": "America/Whitehorse",
+}
+
+# Old name for the win_tz variable:
+tz_names = win_tz
+
+tz_win = {
+ "": "Central Standard Time (Mexico)",
+ "Africa/Abidjan": "Greenwich Standard Time",
+ "Africa/Accra": "Greenwich Standard Time",
+ "Africa/Addis_Ababa": "E. Africa Standard Time",
+ "Africa/Algiers": "W. Central Africa Standard Time",
+ "Africa/Asmara": "E. Africa Standard Time",
+ "Africa/Asmera": "E. Africa Standard Time",
+ "Africa/Bamako": "Greenwich Standard Time",
+ "Africa/Bangui": "W. Central Africa Standard Time",
+ "Africa/Banjul": "Greenwich Standard Time",
+ "Africa/Bissau": "Greenwich Standard Time",
+ "Africa/Blantyre": "South Africa Standard Time",
+ "Africa/Brazzaville": "W. Central Africa Standard Time",
+ "Africa/Bujumbura": "South Africa Standard Time",
+ "Africa/Cairo": "Egypt Standard Time",
+ "Africa/Casablanca": "Morocco Standard Time",
+ "Africa/Ceuta": "Romance Standard Time",
+ "Africa/Conakry": "Greenwich Standard Time",
+ "Africa/Dakar": "Greenwich Standard Time",
+ "Africa/Dar_es_Salaam": "E. Africa Standard Time",
+ "Africa/Djibouti": "E. Africa Standard Time",
+ "Africa/Douala": "W. Central Africa Standard Time",
+ "Africa/El_Aaiun": "Morocco Standard Time",
+ "Africa/Freetown": "Greenwich Standard Time",
+ "Africa/Gaborone": "South Africa Standard Time",
+ "Africa/Harare": "South Africa Standard Time",
+ "Africa/Johannesburg": "South 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",
+ "Africa/Kinshasa": "W. Central Africa Standard Time",
+ "Africa/Lagos": "W. Central Africa Standard Time",
+ "Africa/Libreville": "W. Central Africa Standard Time",
+ "Africa/Lome": "Greenwich Standard Time",
+ "Africa/Luanda": "W. Central Africa Standard Time",
+ "Africa/Lubumbashi": "South Africa Standard Time",
+ "Africa/Lusaka": "South Africa Standard Time",
+ "Africa/Malabo": "W. Central Africa Standard Time",
+ "Africa/Maputo": "South Africa Standard Time",
+ "Africa/Maseru": "South Africa Standard Time",
+ "Africa/Mbabane": "South Africa Standard Time",
+ "Africa/Mogadishu": "E. Africa Standard Time",
+ "Africa/Monrovia": "Greenwich Standard Time",
+ "Africa/Nairobi": "E. Africa Standard Time",
+ "Africa/Ndjamena": "W. Central Africa Standard Time",
+ "Africa/Niamey": "W. Central Africa Standard Time",
+ "Africa/Nouakchott": "Greenwich Standard Time",
+ "Africa/Ouagadougou": "Greenwich Standard Time",
+ "Africa/Porto-Novo": "W. Central Africa 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",
+ "Africa/Windhoek": "Namibia Standard Time",
+ "America/Adak": "Aleutian Standard Time",
+ "America/Anchorage": "Alaskan Standard Time",
+ "America/Anguilla": "SA Western Standard Time",
+ "America/Antigua": "SA Western Standard Time",
+ "America/Araguaina": "Tocantins Standard Time",
+ "America/Argentina/Buenos_Aires": "Argentina Standard Time",
+ "America/Argentina/Catamarca": "Argentina Standard Time",
+ "America/Argentina/ComodRivadavia": "Argentina Standard Time",
+ "America/Argentina/Cordoba": "Argentina Standard Time",
+ "America/Argentina/Jujuy": "Argentina Standard Time",
+ "America/Argentina/La_Rioja": "Argentina Standard Time",
+ "America/Argentina/Mendoza": "Argentina Standard Time",
+ "America/Argentina/Rio_Gallegos": "Argentina Standard Time",
+ "America/Argentina/Salta": "Argentina Standard Time",
+ "America/Argentina/San_Juan": "Argentina Standard Time",
+ "America/Argentina/San_Luis": "Argentina Standard Time",
+ "America/Argentina/Tucuman": "Argentina Standard Time",
+ "America/Argentina/Ushuaia": "Argentina Standard Time",
+ "America/Aruba": "SA Western Standard Time",
+ "America/Asuncion": "Paraguay Standard Time",
+ "America/Atikokan": "SA Pacific Standard Time",
+ "America/Atka": "Aleutian Standard Time",
+ "America/Bahia": "Bahia Standard Time",
+ "America/Bahia_Banderas": "Central Standard Time (Mexico)",
+ "America/Barbados": "SA Western Standard Time",
+ "America/Belem": "SA Eastern Standard Time",
+ "America/Belize": "Central America Standard Time",
+ "America/Blanc-Sablon": "SA Western Standard Time",
+ "America/Boa_Vista": "SA Western Standard Time",
+ "America/Bogota": "SA Pacific Standard Time",
+ "America/Boise": "Mountain Standard Time",
+ "America/Buenos_Aires": "Argentina Standard Time",
+ "America/Cambridge_Bay": "Mountain Standard Time",
+ "America/Campo_Grande": "Central Brazilian Standard Time",
+ "America/Cancun": "Eastern Standard Time (Mexico)",
+ "America/Caracas": "Venezuela Standard Time",
+ "America/Catamarca": "Argentina Standard Time",
+ "America/Cayenne": "SA Eastern Standard Time",
+ "America/Cayman": "SA Pacific Standard Time",
+ "America/Chicago": "Central Standard Time",
+ "America/Chihuahua": "Central Standard Time (Mexico)",
+ "America/Ciudad_Juarez": "Mountain Standard Time",
+ "America/Coral_Harbour": "SA Pacific Standard Time",
+ "America/Cordoba": "Argentina Standard Time",
+ "America/Costa_Rica": "Central America Standard Time",
+ "America/Creston": "US Mountain Standard Time",
+ "America/Cuiaba": "Central Brazilian Standard Time",
+ "America/Curacao": "SA Western 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",
+ "America/Dominica": "SA Western Standard Time",
+ "America/Edmonton": "Mountain Standard Time",
+ "America/Eirunepe": "SA Pacific Standard Time",
+ "America/El_Salvador": "Central America Standard Time",
+ "America/Ensenada": "Pacific Standard Time (Mexico)",
+ "America/Fort_Nelson": "US Mountain Standard Time",
+ "America/Fort_Wayne": "US Eastern Standard Time",
+ "America/Fortaleza": "SA Eastern Standard Time",
+ "America/Glace_Bay": "Atlantic Standard Time",
+ "America/Godthab": "Greenland Standard Time",
+ "America/Goose_Bay": "Atlantic Standard Time",
+ "America/Grand_Turk": "Turks And Caicos Standard Time",
+ "America/Grenada": "SA Western Standard Time",
+ "America/Guadeloupe": "SA Western Standard Time",
+ "America/Guatemala": "Central America Standard Time",
+ "America/Guayaquil": "SA Pacific Standard Time",
+ "America/Guyana": "SA Western Standard Time",
+ "America/Halifax": "Atlantic Standard Time",
+ "America/Havana": "Cuba Standard Time",
+ "America/Hermosillo": "US Mountain Standard Time",
+ "America/Indiana/Indianapolis": "US Eastern Standard Time",
+ "America/Indiana/Knox": "Central Standard Time",
+ "America/Indiana/Marengo": "US Eastern Standard Time",
+ "America/Indiana/Petersburg": "Eastern Standard Time",
+ "America/Indiana/Tell_City": "Central Standard Time",
+ "America/Indiana/Vevay": "US Eastern Standard Time",
+ "America/Indiana/Vincennes": "Eastern Standard Time",
+ "America/Indiana/Winamac": "Eastern Standard Time",
+ "America/Indianapolis": "US Eastern Standard Time",
+ "America/Inuvik": "Mountain Standard Time",
+ "America/Iqaluit": "Eastern Standard Time",
+ "America/Jamaica": "SA Pacific Standard Time",
+ "America/Jujuy": "Argentina Standard Time",
+ "America/Juneau": "Alaskan Standard Time",
+ "America/Kentucky/Louisville": "Eastern Standard Time",
+ "America/Kentucky/Monticello": "Eastern Standard Time",
+ "America/Knox_IN": "Central Standard Time",
+ "America/Kralendijk": "SA Western Standard Time",
+ "America/La_Paz": "SA Western Standard Time",
+ "America/Lima": "SA Pacific Standard Time",
+ "America/Los_Angeles": "Pacific Standard Time",
+ "America/Louisville": "Eastern Standard Time",
+ "America/Lower_Princes": "SA Western Standard Time",
+ "America/Maceio": "SA Eastern Standard Time",
+ "America/Managua": "Central America Standard Time",
+ "America/Manaus": "SA Western Standard Time",
+ "America/Marigot": "SA Western Standard Time",
+ "America/Martinique": "SA Western Standard Time",
+ "America/Matamoros": "Central Standard Time",
+ "America/Mazatlan": "Mountain Standard Time (Mexico)",
+ "America/Mendoza": "Argentina Standard Time",
+ "America/Menominee": "Central Standard Time",
+ "America/Merida": "Central Standard Time (Mexico)",
+ "America/Metlakatla": "Alaskan Standard Time",
+ "America/Mexico_City": "Central Standard Time (Mexico)",
+ "America/Miquelon": "Saint Pierre Standard Time",
+ "America/Moncton": "Atlantic Standard Time",
+ "America/Monterrey": "Central Standard Time (Mexico)",
+ "America/Montevideo": "Montevideo Standard Time",
+ "America/Montreal": "Eastern Standard Time",
+ "America/Montserrat": "SA Western Standard Time",
+ "America/Nassau": "Eastern Standard Time",
+ "America/New_York": "Eastern Standard Time",
+ "America/Nipigon": "Eastern Standard Time",
+ "America/Nome": "Alaskan Standard Time",
+ "America/Noronha": "UTC-02",
+ "America/North_Dakota/Beulah": "Central Standard Time",
+ "America/North_Dakota/Center": "Central Standard Time",
+ "America/North_Dakota/New_Salem": "Central Standard Time",
+ "America/Nuuk": "Greenland Standard Time",
+ "America/Ojinaga": "Central Standard Time",
+ "America/Panama": "SA Pacific Standard Time",
+ "America/Pangnirtung": "Eastern Standard Time",
+ "America/Paramaribo": "SA Eastern Standard Time",
+ "America/Phoenix": "US Mountain Standard Time",
+ "America/Port-au-Prince": "Haiti Standard Time",
+ "America/Port_of_Spain": "SA Western Standard Time",
+ "America/Porto_Acre": "SA Pacific Standard Time",
+ "America/Porto_Velho": "SA Western Standard Time",
+ "America/Puerto_Rico": "SA Western Standard Time",
+ "America/Punta_Arenas": "Magallanes Standard Time",
+ "America/Rainy_River": "Central Standard Time",
+ "America/Rankin_Inlet": "Central Standard Time",
+ "America/Recife": "SA Eastern Standard Time",
+ "America/Regina": "Canada Central Standard Time",
+ "America/Resolute": "Central Standard Time",
+ "America/Rio_Branco": "SA Pacific Standard Time",
+ "America/Rosario": "Argentina Standard Time",
+ "America/Santa_Isabel": "Pacific Standard Time (Mexico)",
+ "America/Santarem": "SA Eastern Standard Time",
+ "America/Santiago": "Pacific SA Standard Time",
+ "America/Santo_Domingo": "SA Western Standard Time",
+ "America/Sao_Paulo": "E. South America Standard Time",
+ "America/Scoresbysund": "Azores Standard Time",
+ "America/Shiprock": "Mountain Standard Time",
+ "America/Sitka": "Alaskan Standard Time",
+ "America/St_Barthelemy": "SA Western Standard Time",
+ "America/St_Johns": "Newfoundland Standard Time",
+ "America/St_Kitts": "SA Western Standard Time",
+ "America/St_Lucia": "SA Western Standard Time",
+ "America/St_Thomas": "SA Western Standard Time",
+ "America/St_Vincent": "SA Western Standard Time",
+ "America/Swift_Current": "Canada Central Standard Time",
+ "America/Tegucigalpa": "Central America Standard Time",
+ "America/Thule": "Atlantic Standard Time",
+ "America/Thunder_Bay": "Eastern Standard Time",
+ "America/Tijuana": "Pacific Standard Time (Mexico)",
+ "America/Toronto": "Eastern Standard Time",
+ "America/Tortola": "SA Western Standard Time",
+ "America/Vancouver": "Pacific Standard Time",
+ "America/Virgin": "SA Western Standard Time",
+ "America/Whitehorse": "Yukon Standard Time",
+ "America/Winnipeg": "Central Standard Time",
+ "America/Yakutat": "Alaskan Standard Time",
+ "America/Yellowknife": "Mountain Standard Time",
+ "Antarctica/Casey": "Central Pacific Standard Time",
+ "Antarctica/Davis": "SE Asia Standard Time",
+ "Antarctica/DumontDUrville": "West 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",
+ "Antarctica/Rothera": "SA Eastern Standard Time",
+ "Antarctica/South_Pole": "New Zealand Standard Time",
+ "Antarctica/Syowa": "E. Africa Standard Time",
+ "Antarctica/Vostok": "Central Asia Standard Time",
+ "Arctic/Longyearbyen": "W. Europe Standard Time",
+ "Asia/Aden": "Arab Standard Time",
+ "Asia/Almaty": "Central Asia Standard Time",
+ "Asia/Amman": "Jordan Standard Time",
+ "Asia/Anadyr": "Russia Time Zone 11",
+ "Asia/Aqtau": "West Asia Standard Time",
+ "Asia/Aqtobe": "West Asia Standard Time",
+ "Asia/Ashgabat": "West Asia Standard Time",
+ "Asia/Ashkhabad": "West Asia Standard Time",
+ "Asia/Atyrau": "West Asia Standard Time",
+ "Asia/Baghdad": "Arabic Standard Time",
+ "Asia/Bahrain": "Arab Standard Time",
+ "Asia/Baku": "Azerbaijan Standard Time",
+ "Asia/Bangkok": "SE Asia Standard Time",
+ "Asia/Barnaul": "Altai Standard Time",
+ "Asia/Beirut": "Middle East Standard Time",
+ "Asia/Bishkek": "Central Asia Standard Time",
+ "Asia/Brunei": "Singapore Standard Time",
+ "Asia/Calcutta": "India Standard Time",
+ "Asia/Chita": "Transbaikal Standard Time",
+ "Asia/Choibalsan": "Ulaanbaatar Standard Time",
+ "Asia/Chongqing": "China Standard Time",
+ "Asia/Chungking": "China Standard Time",
+ "Asia/Colombo": "Sri Lanka Standard Time",
+ "Asia/Dacca": "Bangladesh Standard Time",
+ "Asia/Damascus": "Syria Standard Time",
+ "Asia/Dhaka": "Bangladesh Standard Time",
+ "Asia/Dili": "Tokyo Standard Time",
+ "Asia/Dubai": "Arabian Standard Time",
+ "Asia/Dushanbe": "West Asia Standard Time",
+ "Asia/Famagusta": "GTB Standard Time",
+ "Asia/Gaza": "West Bank Standard Time",
+ "Asia/Harbin": "China Standard Time",
+ "Asia/Hebron": "West Bank Standard Time",
+ "Asia/Ho_Chi_Minh": "SE Asia Standard Time",
+ "Asia/Hong_Kong": "China Standard Time",
+ "Asia/Hovd": "W. Mongolia Standard Time",
+ "Asia/Irkutsk": "North Asia East Standard Time",
+ "Asia/Istanbul": "Turkey Standard Time",
+ "Asia/Jakarta": "SE Asia Standard Time",
+ "Asia/Jayapura": "Tokyo Standard Time",
+ "Asia/Jerusalem": "Israel Standard Time",
+ "Asia/Kabul": "Afghanistan Standard Time",
+ "Asia/Kamchatka": "Russia Time Zone 11",
+ "Asia/Karachi": "Pakistan Standard Time",
+ "Asia/Kashgar": "Central Asia Standard Time",
+ "Asia/Kathmandu": "Nepal Standard Time",
+ "Asia/Katmandu": "Nepal Standard Time",
+ "Asia/Khandyga": "Yakutsk Standard Time",
+ "Asia/Kolkata": "India Standard Time",
+ "Asia/Krasnoyarsk": "North Asia Standard Time",
+ "Asia/Kuala_Lumpur": "Singapore Standard Time",
+ "Asia/Kuching": "Singapore Standard Time",
+ "Asia/Kuwait": "Arab Standard Time",
+ "Asia/Macao": "China Standard Time",
+ "Asia/Macau": "China Standard Time",
+ "Asia/Magadan": "Magadan Standard Time",
+ "Asia/Makassar": "Singapore Standard Time",
+ "Asia/Manila": "Singapore Standard Time",
+ "Asia/Muscat": "Arabian Standard Time",
+ "Asia/Nicosia": "GTB Standard Time",
+ "Asia/Novokuznetsk": "North Asia Standard Time",
+ "Asia/Novosibirsk": "N. Central Asia Standard Time",
+ "Asia/Omsk": "Omsk Standard Time",
+ "Asia/Oral": "West Asia Standard Time",
+ "Asia/Phnom_Penh": "SE Asia Standard Time",
+ "Asia/Pontianak": "SE Asia Standard Time",
+ "Asia/Pyongyang": "North Korea Standard Time",
+ "Asia/Qatar": "Arab Standard Time",
+ "Asia/Qostanay": "Central Asia Standard Time",
+ "Asia/Qyzylorda": "Qyzylorda Standard Time",
+ "Asia/Rangoon": "Myanmar Standard Time",
+ "Asia/Riyadh": "Arab Standard Time",
+ "Asia/Saigon": "SE Asia Standard Time",
+ "Asia/Sakhalin": "Sakhalin Standard Time",
+ "Asia/Samarkand": "West Asia Standard Time",
+ "Asia/Seoul": "Korea Standard Time",
+ "Asia/Shanghai": "China Standard Time",
+ "Asia/Singapore": "Singapore Standard Time",
+ "Asia/Srednekolymsk": "Russia Time Zone 10",
+ "Asia/Taipei": "Taipei Standard Time",
+ "Asia/Tashkent": "West Asia Standard Time",
+ "Asia/Tbilisi": "Georgian Standard Time",
+ "Asia/Tehran": "Iran Standard Time",
+ "Asia/Tel_Aviv": "Israel Standard Time",
+ "Asia/Thimbu": "Bangladesh Standard Time",
+ "Asia/Thimphu": "Bangladesh Standard Time",
+ "Asia/Tokyo": "Tokyo Standard Time",
+ "Asia/Tomsk": "Tomsk Standard Time",
+ "Asia/Ujung_Pandang": "Singapore Standard Time",
+ "Asia/Ulaanbaatar": "Ulaanbaatar Standard Time",
+ "Asia/Ulan_Bator": "Ulaanbaatar Standard Time",
+ "Asia/Urumqi": "Central Asia Standard Time",
+ "Asia/Ust-Nera": "Vladivostok Standard Time",
+ "Asia/Vientiane": "SE Asia Standard Time",
+ "Asia/Vladivostok": "Vladivostok Standard Time",
+ "Asia/Yakutsk": "Yakutsk Standard Time",
+ "Asia/Yangon": "Myanmar Standard Time",
+ "Asia/Yekaterinburg": "Ekaterinburg Standard Time",
+ "Asia/Yerevan": "Caucasus Standard Time",
+ "Atlantic/Azores": "Azores Standard Time",
+ "Atlantic/Bermuda": "Atlantic Standard Time",
+ "Atlantic/Canary": "GMT Standard Time",
+ "Atlantic/Cape_Verde": "Cape Verde Standard Time",
+ "Atlantic/Faeroe": "GMT Standard Time",
+ "Atlantic/Faroe": "GMT Standard Time",
+ "Atlantic/Jan_Mayen": "W. Europe Standard Time",
+ "Atlantic/Madeira": "GMT Standard Time",
+ "Atlantic/Reykjavik": "Greenwich Standard Time",
+ "Atlantic/South_Georgia": "UTC-02",
+ "Atlantic/St_Helena": "Greenwich Standard Time",
+ "Atlantic/Stanley": "SA Eastern Standard Time",
+ "Australia/ACT": "AUS Eastern Standard Time",
+ "Australia/Adelaide": "Cen. Australia Standard Time",
+ "Australia/Brisbane": "E. Australia Standard Time",
+ "Australia/Broken_Hill": "Cen. Australia Standard Time",
+ "Australia/Canberra": "AUS Eastern Standard Time",
+ "Australia/Currie": "Tasmania Standard Time",
+ "Australia/Darwin": "AUS Central Standard Time",
+ "Australia/Eucla": "Aus Central W. Standard Time",
+ "Australia/Hobart": "Tasmania Standard Time",
+ "Australia/LHI": "Lord Howe Standard Time",
+ "Australia/Lindeman": "E. Australia Standard Time",
+ "Australia/Lord_Howe": "Lord Howe Standard Time",
+ "Australia/Melbourne": "AUS Eastern Standard Time",
+ "Australia/NSW": "AUS Eastern Standard Time",
+ "Australia/North": "AUS Central Standard Time",
+ "Australia/Perth": "W. Australia Standard Time",
+ "Australia/Queensland": "E. Australia Standard Time",
+ "Australia/South": "Cen. Australia Standard Time",
+ "Australia/Sydney": "AUS Eastern Standard Time",
+ "Australia/Tasmania": "Tasmania Standard Time",
+ "Australia/Victoria": "AUS Eastern Standard Time",
+ "Australia/West": "W. Australia Standard Time",
+ "Australia/Yancowinna": "Cen. Australia Standard Time",
+ "Brazil/Acre": "SA Pacific Standard Time",
+ "Brazil/DeNoronha": "UTC-02",
+ "Brazil/East": "E. South America Standard Time",
+ "Brazil/West": "SA Western Standard Time",
+ "CST6CDT": "Central Standard Time",
+ "Canada/Atlantic": "Atlantic Standard Time",
+ "Canada/Central": "Central Standard Time",
+ "Canada/Eastern": "Eastern Standard Time",
+ "Canada/Mountain": "Mountain Standard Time",
+ "Canada/Newfoundland": "Newfoundland Standard Time",
+ "Canada/Pacific": "Pacific Standard Time",
+ "Canada/Saskatchewan": "Canada Central Standard Time",
+ "Canada/Yukon": "Yukon Standard Time",
+ "Chile/Continental": "Pacific SA Standard Time",
+ "Chile/EasterIsland": "Easter Island Standard Time",
+ "Cuba": "Cuba Standard Time",
+ "EST5EDT": "Eastern Standard Time",
+ "Egypt": "Egypt Standard Time",
+ "Eire": "GMT Standard Time",
+ "Etc/GMT": "UTC",
+ "Etc/GMT+0": "UTC",
+ "Etc/GMT+1": "Cape Verde Standard Time",
+ "Etc/GMT+10": "Hawaiian Standard Time",
+ "Etc/GMT+11": "UTC-11",
+ "Etc/GMT+12": "Dateline Standard Time",
+ "Etc/GMT+2": "UTC-02",
+ "Etc/GMT+3": "SA Eastern Standard Time",
+ "Etc/GMT+4": "SA Western Standard Time",
+ "Etc/GMT+5": "SA Pacific Standard Time",
+ "Etc/GMT+6": "Central America Standard Time",
+ "Etc/GMT+7": "US Mountain Standard Time",
+ "Etc/GMT+8": "UTC-08",
+ "Etc/GMT+9": "UTC-09",
+ "Etc/GMT-0": "UTC",
+ "Etc/GMT-1": "W. Central Africa Standard Time",
+ "Etc/GMT-10": "West Pacific Standard Time",
+ "Etc/GMT-11": "Central Pacific Standard Time",
+ "Etc/GMT-12": "UTC+12",
+ "Etc/GMT-13": "UTC+13",
+ "Etc/GMT-14": "Line Islands Standard Time",
+ "Etc/GMT-2": "South Africa Standard Time",
+ "Etc/GMT-3": "E. Africa Standard Time",
+ "Etc/GMT-4": "Arabian Standard Time",
+ "Etc/GMT-5": "West Asia Standard Time",
+ "Etc/GMT-6": "Central Asia Standard Time",
+ "Etc/GMT-7": "SE Asia Standard Time",
+ "Etc/GMT-8": "Singapore Standard Time",
+ "Etc/GMT-9": "Tokyo Standard Time",
+ "Etc/GMT0": "UTC",
+ "Etc/Greenwich": "UTC",
+ "Etc/UCT": "UTC",
+ "Etc/UTC": "UTC",
+ "Etc/Universal": "UTC",
+ "Etc/Zulu": "UTC",
+ "Europe/Amsterdam": "W. Europe Standard Time",
+ "Europe/Andorra": "W. Europe Standard Time",
+ "Europe/Astrakhan": "Astrakhan Standard Time",
+ "Europe/Athens": "GTB Standard Time",
+ "Europe/Belfast": "GMT Standard Time",
+ "Europe/Belgrade": "Central Europe Standard Time",
+ "Europe/Berlin": "W. Europe Standard Time",
+ "Europe/Bratislava": "Central Europe Standard Time",
+ "Europe/Brussels": "Romance Standard Time",
+ "Europe/Bucharest": "GTB Standard Time",
+ "Europe/Budapest": "Central Europe Standard Time",
+ "Europe/Busingen": "W. Europe Standard Time",
+ "Europe/Chisinau": "E. Europe Standard Time",
+ "Europe/Copenhagen": "Romance Standard Time",
+ "Europe/Dublin": "GMT Standard Time",
+ "Europe/Gibraltar": "W. Europe Standard Time",
+ "Europe/Guernsey": "GMT Standard Time",
+ "Europe/Helsinki": "FLE Standard Time",
+ "Europe/Isle_of_Man": "GMT Standard Time",
+ "Europe/Istanbul": "Turkey Standard Time",
+ "Europe/Jersey": "GMT Standard Time",
+ "Europe/Kaliningrad": "Kaliningrad Standard Time",
+ "Europe/Kiev": "FLE Standard Time",
+ "Europe/Kirov": "Russian Standard Time",
+ "Europe/Kyiv": "FLE Standard Time",
+ "Europe/Lisbon": "GMT Standard Time",
+ "Europe/Ljubljana": "Central Europe Standard Time",
+ "Europe/London": "GMT Standard Time",
+ "Europe/Luxembourg": "W. Europe Standard Time",
+ "Europe/Madrid": "Romance Standard Time",
+ "Europe/Malta": "W. Europe Standard Time",
+ "Europe/Mariehamn": "FLE Standard Time",
+ "Europe/Minsk": "Belarus Standard Time",
+ "Europe/Monaco": "W. Europe Standard Time",
+ "Europe/Moscow": "Russian Standard Time",
+ "Europe/Nicosia": "GTB Standard Time",
+ "Europe/Oslo": "W. Europe Standard Time",
+ "Europe/Paris": "Romance Standard Time",
+ "Europe/Podgorica": "Central Europe Standard Time",
+ "Europe/Prague": "Central Europe Standard Time",
+ "Europe/Riga": "FLE Standard Time",
+ "Europe/Rome": "W. Europe Standard Time",
+ "Europe/Samara": "Russia Time Zone 3",
+ "Europe/San_Marino": "W. Europe Standard Time",
+ "Europe/Sarajevo": "Central European Standard Time",
+ "Europe/Saratov": "Saratov Standard Time",
+ "Europe/Simferopol": "Russian Standard Time",
+ "Europe/Skopje": "Central European Standard Time",
+ "Europe/Sofia": "FLE Standard Time",
+ "Europe/Stockholm": "W. Europe Standard Time",
+ "Europe/Tallinn": "FLE Standard Time",
+ "Europe/Tirane": "Central Europe Standard Time",
+ "Europe/Tiraspol": "E. Europe Standard Time",
+ "Europe/Ulyanovsk": "Astrakhan Standard Time",
+ "Europe/Uzhgorod": "FLE Standard Time",
+ "Europe/Vaduz": "W. Europe Standard Time",
+ "Europe/Vatican": "W. Europe Standard Time",
+ "Europe/Vienna": "W. Europe Standard Time",
+ "Europe/Vilnius": "FLE Standard Time",
+ "Europe/Volgograd": "Volgograd Standard Time",
+ "Europe/Warsaw": "Central European Standard Time",
+ "Europe/Zagreb": "Central European Standard Time",
+ "Europe/Zaporozhye": "FLE Standard Time",
+ "Europe/Zurich": "W. Europe Standard Time",
+ "GB": "GMT Standard Time",
+ "GB-Eire": "GMT Standard Time",
+ "GMT+0": "UTC",
+ "GMT-0": "UTC",
+ "GMT0": "UTC",
+ "Greenwich": "UTC",
+ "Hongkong": "China Standard Time",
+ "Iceland": "Greenwich Standard Time",
+ "Indian/Antananarivo": "E. Africa Standard Time",
+ "Indian/Chagos": "Central Asia Standard Time",
+ "Indian/Christmas": "SE Asia Standard Time",
+ "Indian/Cocos": "Myanmar Standard Time",
+ "Indian/Comoro": "E. Africa Standard Time",
+ "Indian/Kerguelen": "West Asia Standard Time",
+ "Indian/Mahe": "Mauritius Standard Time",
+ "Indian/Maldives": "West Asia Standard Time",
+ "Indian/Mauritius": "Mauritius Standard Time",
+ "Indian/Mayotte": "E. Africa Standard Time",
+ "Indian/Reunion": "Mauritius Standard Time",
+ "Iran": "Iran Standard Time",
+ "Israel": "Israel Standard Time",
+ "Jamaica": "SA Pacific Standard Time",
+ "Japan": "Tokyo Standard Time",
+ "Kwajalein": "UTC+12",
+ "Libya": "Libya Standard Time",
+ "MST7MDT": "Mountain Standard Time",
+ "Mexico/BajaNorte": "Pacific Standard Time (Mexico)",
+ "Mexico/BajaSur": "Mountain Standard Time (Mexico)",
+ "Mexico/General": "Central Standard Time (Mexico)",
+ "NZ": "New Zealand Standard Time",
+ "NZ-CHAT": "Chatham Islands Standard Time",
+ "Navajo": "Mountain Standard Time",
+ "PRC": "China Standard Time",
+ "PST8PDT": "Pacific Standard Time",
+ "Pacific/Apia": "Samoa Standard Time",
+ "Pacific/Auckland": "New Zealand Standard Time",
+ "Pacific/Bougainville": "Bougainville Standard Time",
+ "Pacific/Chatham": "Chatham Islands Standard Time",
+ "Pacific/Chuuk": "West Pacific Standard Time",
+ "Pacific/Easter": "Easter Island Standard Time",
+ "Pacific/Efate": "Central Pacific Standard Time",
+ "Pacific/Enderbury": "UTC+13",
+ "Pacific/Fakaofo": "UTC+13",
+ "Pacific/Fiji": "Fiji Standard Time",
+ "Pacific/Funafuti": "UTC+12",
+ "Pacific/Galapagos": "Central America Standard Time",
+ "Pacific/Gambier": "UTC-09",
+ "Pacific/Guadalcanal": "Central Pacific Standard Time",
+ "Pacific/Guam": "West Pacific Standard Time",
+ "Pacific/Honolulu": "Hawaiian Standard Time",
+ "Pacific/Johnston": "Hawaiian Standard Time",
+ "Pacific/Kanton": "UTC+13",
+ "Pacific/Kiritimati": "Line Islands Standard Time",
+ "Pacific/Kosrae": "Central Pacific Standard Time",
+ "Pacific/Kwajalein": "UTC+12",
+ "Pacific/Majuro": "UTC+12",
+ "Pacific/Marquesas": "Marquesas Standard Time",
+ "Pacific/Midway": "UTC-11",
+ "Pacific/Nauru": "UTC+12",
+ "Pacific/Niue": "UTC-11",
+ "Pacific/Norfolk": "Norfolk Standard Time",
+ "Pacific/Noumea": "Central Pacific Standard Time",
+ "Pacific/Pago_Pago": "UTC-11",
+ "Pacific/Palau": "Tokyo Standard Time",
+ "Pacific/Pitcairn": "UTC-08",
+ "Pacific/Pohnpei": "Central Pacific Standard Time",
+ "Pacific/Ponape": "Central Pacific Standard Time",
+ "Pacific/Port_Moresby": "West Pacific Standard Time",
+ "Pacific/Rarotonga": "Hawaiian Standard Time",
+ "Pacific/Saipan": "West Pacific Standard Time",
+ "Pacific/Samoa": "UTC-11",
+ "Pacific/Tahiti": "Hawaiian Standard Time",
+ "Pacific/Tarawa": "UTC+12",
+ "Pacific/Tongatapu": "Tonga Standard Time",
+ "Pacific/Truk": "West Pacific Standard Time",
+ "Pacific/Wake": "UTC+12",
+ "Pacific/Wallis": "UTC+12",
+ "Pacific/Yap": "West Pacific Standard Time",
+ "Poland": "Central European Standard Time",
+ "Portugal": "GMT Standard Time",
+ "ROC": "Taipei 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",
+ "US/Central": "Central Standard Time",
+ "US/Eastern": "Eastern Standard Time",
+ "US/Hawaii": "Hawaiian Standard Time",
+ "US/Indiana-Starke": "Central Standard Time",
+ "US/Michigan": "Eastern Standard Time",
+ "US/Mountain": "Mountain Standard Time",
+ "US/Pacific": "Pacific Standard Time",
+ "US/Samoa": "UTC-11",
+ "UTC": "UTC",
+ "Universal": "UTC",
+ "W-SU": "Russian Standard Time",
+ "Zulu": "UTC",
+}
diff --git a/contrib/python/tzlocal/py3/ya.make b/contrib/python/tzlocal/py3/ya.make
new file mode 100644
index 0000000000..4342acb95c
--- /dev/null
+++ b/contrib/python/tzlocal/py3/ya.make
@@ -0,0 +1,35 @@
+# Generated by devtools/yamaker (pypi).
+
+PY3_LIBRARY()
+
+VERSION(5.2)
+
+LICENSE(MIT)
+
+PEERDIR(
+ contrib/python/tzdata
+)
+
+NO_LINT()
+
+NO_CHECK_IMPORTS(
+ tzlocal.win32
+)
+
+PY_SRCS(
+ TOP_LEVEL
+ tzlocal/__init__.py
+ tzlocal/unix.py
+ tzlocal/utils.py
+ tzlocal/win32.py
+ tzlocal/windows_tz.py
+)
+
+RESOURCE_FILES(
+ PREFIX contrib/python/tzlocal/py3/
+ .dist-info/METADATA
+ .dist-info/top_level.txt
+ tzlocal/py.typed
+)
+
+END()
diff --git a/contrib/python/tzlocal/ya.make b/contrib/python/tzlocal/ya.make
new file mode 100644
index 0000000000..b29d8c6c04
--- /dev/null
+++ b/contrib/python/tzlocal/ya.make
@@ -0,0 +1,18 @@
+PY23_LIBRARY()
+
+LICENSE(Service-Py23-Proxy)
+
+IF (PYTHON2)
+ PEERDIR(contrib/python/tzlocal/py2)
+ELSE()
+ PEERDIR(contrib/python/tzlocal/py3)
+ENDIF()
+
+NO_LINT()
+
+END()
+
+RECURSE(
+ py2
+ py3
+)