diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2021-02-07 07:34:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2021-02-07 07:50:21 +0000 |
commit | fe534d5229de5e83dccdfa3e4ba3c1b29bd38a71 (patch) | |
tree | b6c5cd613e258116b1f732732c78f87b3d5f6e50 /pytzdata/__init__.py | |
parent | Initial commit. (diff) | |
download | pytzdata-upstream.tar.xz pytzdata-upstream.zip |
Adding upstream version 2020.1+dfsg.upstream/2010.1+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'pytzdata/__init__.py')
-rw-r--r-- | pytzdata/__init__.py | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/pytzdata/__init__.py b/pytzdata/__init__.py new file mode 100644 index 0000000..22940da --- /dev/null +++ b/pytzdata/__init__.py @@ -0,0 +1,122 @@ +# -*- coding: utf-8 -*- + +import os + +from .exceptions import TimezoneNotFound +from ._timezones import timezones +from ._compat import FileNotFoundError + + +DEFAULT_DIRECTORY = os.path.join( + os.path.dirname(__file__), + 'zoneinfo' +) + +_DIRECTORY = os.getenv('PYTZDATA_TZDATADIR', DEFAULT_DIRECTORY) + +_TIMEZONES = {} + +INVALID_ZONES = ['Factory', 'leapseconds', 'localtime', 'posixrules'] + + +def tz_file(name): + """ + Open a timezone file from the zoneinfo subdir for reading. + + :param name: The name of the timezone. + :type name: str + + :rtype: file + """ + try: + filepath = tz_path(name) + + return open(filepath, 'rb') + except TimezoneNotFound: + # http://bugs.launchpad.net/bugs/383171 - we avoid using this + # unless absolutely necessary to help when a broken version of + # pkg_resources is installed. + try: + from pkg_resources import resource_stream + except ImportError: + resource_stream = None + + if resource_stream is not None: + try: + return resource_stream(__name__, 'zoneinfo/' + name) + except FileNotFoundError: + return tz_path(name) + + raise + + +def tz_path(name): + """ + Return the path to a timezone file. + + :param name: The name of the timezone. + :type name: str + + :rtype: str + """ + if not name: + raise ValueError('Invalid timezone') + + name_parts = name.lstrip('/').split('/') + + for part in name_parts: + if part == os.path.pardir or os.path.sep in part: + raise ValueError('Bad path segment: %r' % part) + + filepath = os.path.join(_DIRECTORY, *name_parts) + + if not os.path.exists(filepath): + raise TimezoneNotFound('Timezone {} not found at {}'.format(name, filepath)) + + return filepath + + +def set_directory(directory=None): + global _DIRECTORY + + if directory is None: + directory = os.getenv('PYTZDATA_TZDATADIR', DEFAULT_DIRECTORY) + + _DIRECTORY = directory + + +def get_timezones(): + """ + Get the supported timezones. + + The list will be cached unless you set the "fresh" attribute to True. + + :param fresh: Whether to get a fresh list or not + :type fresh: bool + + :rtype: tuple + """ + base_dir = _DIRECTORY + zones = () + + for root, dirs, files in os.walk(base_dir): + for basename in files: + zone = os.path.join(root, basename) + if os.path.isdir(zone): + continue + + zone = os.path.relpath(zone, base_dir) + + with open(os.path.join(root, basename), 'rb') as fd: + if fd.read(4) == b'TZif' and zone not in INVALID_ZONES: + zones = zones + (zone,) + + return tuple(sorted(zones)) + + +def _get_suffix(name): + i = name.rfind('.') + if 0 < i < len(name) - 1: + return name[i:] + else: + return '' |