Skip to content

Commit ca92b0e

Browse files
Merge pull request pandas-dev#159 from manahl/remove_tz_files
Remove timezone path dependency on *nix
2 parents 38574fc + 5fb3666 commit ca92b0e

File tree

5 files changed

+26
-59
lines changed

5 files changed

+26
-59
lines changed

arctic/date/_mktz.py

+16-43
Original file line numberDiff line numberDiff line change
@@ -2,56 +2,26 @@
22
import os
33
import dateutil
44
import tzlocal
5-
6-
DEFAULT_TIME_ZONE_NAME = tzlocal.get_localzone().zone # 'Europe/London'
7-
TIME_ZONE_DATA_SOURCE = u'/usr/share/zoneinfo/'
5+
import six
86

97

108
class TimezoneError(Exception):
119
pass
1210

1311

14-
class tzfile(dateutil.tz.tzfile):
15-
16-
def _find_ttinfo(self, dtm, laststd=0):
17-
"""Faster version of parent class's _find_ttinfo() as this uses bisect rather than a linear search."""
18-
if dtm is None:
19-
# This will happen, for example, when a datetime.time object gets utcoffset() called.
20-
raise ValueError('tzinfo object can not calculate offset for date %s' % dtm)
21-
ts = ((dtm.toordinal() - dateutil.tz.EPOCHORDINAL) * 86400
22-
+ dtm.hour * 3600
23-
+ dtm.minute * 60
24-
+ dtm.second)
25-
idx = bisect.bisect_right(self._trans_list, ts)
26-
if len(self._trans_list) == 0 or idx == len(self._trans_list):
27-
return self._ttinfo_std
28-
if idx == 0:
29-
return self._ttinfo_before
30-
if laststd:
31-
while idx > 0:
32-
tti = self._trans_idx[idx - 1]
33-
if not tti.isdst:
34-
return tti
35-
idx -= 1
36-
else:
37-
return self._ttinfo_std
38-
else:
39-
return self._trans_idx[idx - 1]
40-
41-
4212
def mktz(zone=None):
4313
"""
44-
Return a new timezone based on the zone using the python-dateutil
45-
package. This convenience method is useful for resolving the timezone
46-
names as dateutil.tz.tzfile requires the full path.
14+
Return a new timezone (tzinfo object) based on the zone using the python-dateutil
15+
package.
4716
4817
The concise name 'mktz' is for convenient when using it on the
4918
console.
5019
5120
Parameters
5221
----------
5322
zone : `String`
54-
The zone for the timezone. This defaults to 'local'.
23+
The zone for the timezone. This defaults to local, returning:
24+
tzlocal.get_localzone()
5525
5626
Returns
5727
-------
@@ -61,14 +31,17 @@ def mktz(zone=None):
6131
- - - - - -
6232
TimezoneError : Raised if a user inputs a bad timezone name.
6333
"""
64-
6534
if zone is None:
66-
zone = DEFAULT_TIME_ZONE_NAME
67-
_path = os.path.join(TIME_ZONE_DATA_SOURCE, zone)
68-
try:
69-
tz = tzfile(_path)
70-
except (ValueError, IOError) as err:
71-
raise TimezoneError('Timezone "%s" can not be read, error: "%s"' % (zone, err))
35+
zone = tzlocal.get_localzone().zone
36+
zone = six.u(zone)
37+
tz = dateutil.tz.gettz(zone)
38+
if not tz:
39+
raise TimezoneError('Timezone "%s" can not be read' % (zone))
7240
# Stash the zone name as an attribute (as pytz does)
73-
tz.zone = zone if not zone.startswith(TIME_ZONE_DATA_SOURCE) else zone[len(TIME_ZONE_DATA_SOURCE):]
41+
if not hasattr(tz, 'zone'):
42+
tz.zone = zone
43+
for p in dateutil.tz.TZPATHS:
44+
if zone.startswith(p):
45+
tz.zone = zone[len(p) + 1:]
46+
break
7447
return tz

tests/integration/tickstore/test_ts_read.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from datetime import datetime as dt
2-
from mock import patch, call
2+
from mock import patch, call, Mock
33
import numpy as np
44
from numpy.testing.utils import assert_array_equal
55
from pandas.util.testing import assert_frame_equal
@@ -287,7 +287,7 @@ def test_date_range_default_timezone(tickstore_lib, tz_name):
287287
},
288288
]
289289

290-
with patch('arctic.date._mktz.DEFAULT_TIME_ZONE_NAME', tz_name):
290+
with patch('tzlocal.get_localzone', return_value=Mock(zone=tz_name)):
291291
tickstore_lib._chunk_size = 1
292292
tickstore_lib.write('SYM', DUMMY_DATA)
293293
df = tickstore_lib.read('SYM', date_range=DateRange(20130101, 20130701), columns=None)

tests/unit/date/test_datetime_to_ms_roundtrip.py

+4-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from datetime import datetime as dt
44
import pytz
55
from arctic.date import mktz, datetime_to_ms, ms_to_datetime
6-
from arctic.date._mktz import DEFAULT_TIME_ZONE_NAME
76
import sys
87

98

@@ -64,20 +63,20 @@ def test_datetime_roundtrip_local_no_tz():
6463

6564

6665
def test_datetime_roundtrip_local_tz():
67-
pdt = datetime.datetime(2012, 6, 12, 12, 12, 12, 123000, tzinfo=mktz(DEFAULT_TIME_ZONE_NAME))
66+
pdt = datetime.datetime(2012, 6, 12, 12, 12, 12, 123000, tzinfo=mktz())
6867
pdt2 = ms_to_datetime(datetime_to_ms(pdt))
6968
assert pdt2 == pdt
7069

71-
pdt = datetime.datetime(2012, 1, 12, 12, 12, 12, 123000, tzinfo=mktz(DEFAULT_TIME_ZONE_NAME))
70+
pdt = datetime.datetime(2012, 1, 12, 12, 12, 12, 123000, tzinfo=mktz())
7271
pdt2 = ms_to_datetime(datetime_to_ms(pdt))
7372
assert pdt2 == pdt
7473

7574

7675
def test_datetime_roundtrip_est_tz():
7776
pdt = datetime.datetime(2012, 6, 12, 12, 12, 12, 123000, tzinfo=mktz('EST'))
7877
pdt2 = ms_to_datetime(datetime_to_ms(pdt))
79-
assert pdt2.replace(tzinfo=mktz(DEFAULT_TIME_ZONE_NAME)) == pdt
78+
assert pdt2.replace(tzinfo=mktz()) == pdt
8079

8180
pdt = datetime.datetime(2012, 1, 12, 12, 12, 12, 123000, tzinfo=mktz('EST'))
8281
pdt2 = ms_to_datetime(datetime_to_ms(pdt))
83-
assert pdt2.replace(tzinfo=mktz(DEFAULT_TIME_ZONE_NAME)) == pdt
82+
assert pdt2.replace(tzinfo=mktz()) == pdt

tests/unit/date/test_mktz.py

+3-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
from datetime import datetime as dt
22
from mock import patch
33
from pytest import raises
4+
import tzlocal
45

56
from arctic.date import mktz, TimezoneError
6-
from arctic.date._mktz import DEFAULT_TIME_ZONE_NAME, tzfile, TIME_ZONE_DATA_SOURCE
7+
8+
DEFAULT_TIME_ZONE_NAME = tzlocal.get_localzone().zone # 'Europe/London'
79

810

911
def test_mktz():
@@ -37,9 +39,3 @@ def test_mktz_fails_if_invalid_timezone():
3739
file_exists.return_value = False
3840
with raises(TimezoneError):
3941
mktz('junk')
40-
41-
42-
def test_tzfile_raises():
43-
t = tzfile(TIME_ZONE_DATA_SOURCE + DEFAULT_TIME_ZONE_NAME)
44-
with raises(ValueError):
45-
t._find_ttinfo(None)

tests/unit/date/test_util.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
from datetime import datetime as dt
55
from arctic.date import datetime_to_ms, ms_to_datetime, mktz, to_pandas_closed_closed, DateRange, OPEN_OPEN, CLOSED_CLOSED
6-
from arctic.date._mktz import DEFAULT_TIME_ZONE_NAME
76
from arctic.date._util import to_dt
87

98

@@ -24,7 +23,7 @@ def test_datetime_to_ms_and_back(pdt):
2423

2524

2625
def test_datetime_to_ms_and_back_microseconds():
27-
pdt = dt(2012, 8, 1, 12, 34, 56, 999999, tzinfo=mktz(DEFAULT_TIME_ZONE_NAME))
26+
pdt = dt(2012, 8, 1, 12, 34, 56, 999999, tzinfo=mktz())
2827
i = datetime_to_ms(pdt)
2928
pdt2 = ms_to_datetime(i)
3029

0 commit comments

Comments
 (0)