Skip to content

Commit fe270cd

Browse files
committed
Fix error on some systems when retrieving local timezone from clock files
1 parent 2d8657b commit fe270cd

File tree

4 files changed

+27
-4
lines changed

4 files changed

+27
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
## Fixed
66

77
- Fixed behavior of the `YY` token in `from_format()`.
8+
- Fixed errors on some systems when retrieving timezone from clock files.
89

910

1011
## [2.0.0] - 2018-05-08

pendulum/tz/local_timezone.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@ def _get_unix_timezone(_root='/'): # type: (str) -> Timezone
176176
# OpenSUSE has a TIMEZONE setting in /etc/sysconfig/clock and
177177
# Gentoo has a TIMEZONE setting in /etc/conf.d/clock
178178
# We look through these files for a timezone:
179-
180179
zone_re = re.compile('\s*ZONE\s*=\s*\"')
181180
timezone_re = re.compile('\s*TIMEZONE\s*=\s*\"')
182181
end_re = re.compile('\"')
@@ -185,6 +184,7 @@ def _get_unix_timezone(_root='/'): # type: (str) -> Timezone
185184
tzpath = os.path.join(_root, filename)
186185
if not os.path.exists(tzpath):
187186
continue
187+
188188
with open(tzpath, 'rt') as tzfile:
189189
data = tzfile.readlines()
190190

@@ -194,13 +194,21 @@ def _get_unix_timezone(_root='/'): # type: (str) -> Timezone
194194
if match is None:
195195
# No ZONE= setting. Look for the TIMEZONE= setting.
196196
match = timezone_re.match(line)
197+
197198
if match is not None:
198199
# Some setting existed
199200
line = line[match.end():]
200201
etctz = line[:end_re.search(line).start()]
201202

202-
# We found a timezone
203-
return Timezone(etctz.replace(' ', '_'))
203+
parts = etctz.replace(' ', '_').split('/')[-2:]
204+
while parts:
205+
tzpath = '/'.join(parts)
206+
try:
207+
return Timezone(tzpath)
208+
except (ValueError, IOError, OSError):
209+
pass
210+
211+
parts.pop(0)
204212

205213
# systemd distributions use symlinks that include the zone name,
206214
# see manpage of localtime(5) and timedatectl(1)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ZONE="/usr/share/zoneinfo/Europe/Zurich"

tests/tz/test_local_timezone.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,22 @@ def test_unix_symlink():
2020
assert tz.name == 'Europe/Paris'
2121

2222

23+
@pytest.mark.skipif(sys.platform == 'win32',
24+
reason='Test only available for UNIX systems')
25+
def test_unix_clock():
26+
# A ZONE setting in the target path of a symbolic linked localtime,
27+
# f ex systemd distributions
28+
local_path = os.path.join(os.path.split(__file__)[0], '..')
29+
tz = _get_unix_timezone(
30+
_root=os.path.join(local_path, 'fixtures', 'tz', 'clock')
31+
)
32+
33+
assert tz.name == 'Europe/Zurich'
34+
35+
2336
@pytest.mark.skipif(sys.platform != 'win32',
2437
reason='Test only available for Windows')
25-
def test_unix_symlink():
38+
def test_windows_timezone():
2639
timezone = _get_windows_timezone()
2740

2841
assert timezone is not None

0 commit comments

Comments
 (0)