Spaces:
Runtime error
Runtime error
import datetime | |
import os | |
import re | |
from babel.localtime._helpers import ( | |
_get_tzinfo, | |
_get_tzinfo_from_file, | |
_get_tzinfo_or_raise, | |
) | |
def _tz_from_env(tzenv: str) -> datetime.tzinfo: | |
if tzenv[0] == ':': | |
tzenv = tzenv[1:] | |
# TZ specifies a file | |
if os.path.exists(tzenv): | |
return _get_tzinfo_from_file(tzenv) | |
# TZ specifies a zoneinfo zone. | |
return _get_tzinfo_or_raise(tzenv) | |
def _get_localzone(_root: str = '/') -> datetime.tzinfo: | |
"""Tries to find the local timezone configuration. | |
This method prefers finding the timezone name and passing that to | |
zoneinfo or 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 = os.environ.get('TZ') | |
if tzenv: | |
return _tz_from_env(tzenv) | |
# This is actually a pretty reliable way to test for the local time | |
# zone on operating systems like OS X. On OS X especially this is the | |
# only one that actually works. | |
try: | |
link_dst = os.readlink('/etc/localtime') | |
except OSError: | |
pass | |
else: | |
pos = link_dst.find('/zoneinfo/') | |
if pos >= 0: | |
zone_name = link_dst[pos + 10:] | |
tzinfo = _get_tzinfo(zone_name) | |
if tzinfo is not None: | |
return tzinfo | |
# Now look for distribution specific configuration files | |
# that contain the timezone name. | |
tzpath = os.path.join(_root, 'etc/timezone') | |
if os.path.exists(tzpath): | |
with open(tzpath, 'rb') as tzfile: | |
data = tzfile.read() | |
# Issue #3 in tzlocal was that /etc/timezone was a zoneinfo file. | |
# That's a misconfiguration, but we need to handle it gracefully: | |
if data[:5] != b'TZif2': | |
etctz = data.strip().decode() | |
# Get rid of host definitions and comments: | |
if ' ' in etctz: | |
etctz, dummy = etctz.split(' ', 1) | |
if '#' in etctz: | |
etctz, dummy = etctz.split('#', 1) | |
return _get_tzinfo_or_raise(etctz.replace(' ', '_')) | |
# 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: | |
timezone_re = re.compile(r'\s*(TIME)?ZONE\s*=\s*"(?P<etctz>.+)"') | |
for filename in ('etc/sysconfig/clock', 'etc/conf.d/clock'): | |
tzpath = os.path.join(_root, filename) | |
if not os.path.exists(tzpath): | |
continue | |
with open(tzpath) as tzfile: | |
for line in tzfile: | |
match = timezone_re.match(line) | |
if match is not None: | |
# We found a timezone | |
etctz = match.group("etctz") | |
return _get_tzinfo_or_raise(etctz.replace(' ', '_')) | |
# 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 | |
return _get_tzinfo_from_file(tzpath) | |
raise LookupError('Can not find any timezone configuration') | |