Skip to content

Commit 54f1b3e

Browse files
jbrockmendeljreback
authored andcommitted
Collect Series timezone tests (pandas-dev#19541)
1 parent 84522a0 commit 54f1b3e

File tree

2 files changed

+296
-255
lines changed

2 files changed

+296
-255
lines changed

pandas/tests/series/test_timezones.py

+293
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
Tests for Series timezone-related methods
4+
"""
5+
from datetime import datetime
6+
7+
import pytest
8+
import pytz
9+
import numpy as np
10+
from dateutil.tz import tzoffset
11+
12+
import pandas.util.testing as tm
13+
from pandas._libs import tslib
14+
from pandas._libs.tslibs import timezones
15+
from pandas.compat import lrange
16+
from pandas.core.indexes.datetimes import date_range
17+
from pandas import Series, Timestamp, DatetimeIndex, Index
18+
19+
20+
class TestSeriesTimezones(object):
21+
# -----------------------------------------------------------------
22+
# Series.tz_localize
23+
def test_series_tz_localize(self):
24+
25+
rng = date_range('1/1/2011', periods=100, freq='H')
26+
ts = Series(1, index=rng)
27+
28+
result = ts.tz_localize('utc')
29+
assert result.index.tz.zone == 'UTC'
30+
31+
# Can't localize if already tz-aware
32+
rng = date_range('1/1/2011', periods=100, freq='H', tz='utc')
33+
ts = Series(1, index=rng)
34+
tm.assert_raises_regex(TypeError, 'Already tz-aware',
35+
ts.tz_localize, 'US/Eastern')
36+
37+
def test_series_tz_localize_ambiguous_bool(self):
38+
# make sure that we are correctly accepting bool values as ambiguous
39+
40+
# GH#14402
41+
ts = Timestamp('2015-11-01 01:00:03')
42+
expected0 = Timestamp('2015-11-01 01:00:03-0500', tz='US/Central')
43+
expected1 = Timestamp('2015-11-01 01:00:03-0600', tz='US/Central')
44+
45+
ser = Series([ts])
46+
expected0 = Series([expected0])
47+
expected1 = Series([expected1])
48+
49+
with pytest.raises(pytz.AmbiguousTimeError):
50+
ser.dt.tz_localize('US/Central')
51+
52+
result = ser.dt.tz_localize('US/Central', ambiguous=True)
53+
tm.assert_series_equal(result, expected0)
54+
55+
result = ser.dt.tz_localize('US/Central', ambiguous=[True])
56+
tm.assert_series_equal(result, expected0)
57+
58+
result = ser.dt.tz_localize('US/Central', ambiguous=False)
59+
tm.assert_series_equal(result, expected1)
60+
61+
result = ser.dt.tz_localize('US/Central', ambiguous=[False])
62+
tm.assert_series_equal(result, expected1)
63+
64+
@pytest.mark.parametrize('tzstr', ['US/Eastern', 'dateutil/US/Eastern'])
65+
def test_series_tz_localize_empty(self, tzstr):
66+
# GH#2248
67+
ser = Series()
68+
69+
ser2 = ser.tz_localize('utc')
70+
assert ser2.index.tz == pytz.utc
71+
72+
ser2 = ser.tz_localize(tzstr)
73+
timezones.tz_compare(ser2.index.tz, timezones.maybe_get_tz(tzstr))
74+
75+
# -----------------------------------------------------------------
76+
# Series.tz_convert
77+
78+
def test_series_tz_convert(self):
79+
rng = date_range('1/1/2011', periods=200, freq='D', tz='US/Eastern')
80+
ts = Series(1, index=rng)
81+
82+
result = ts.tz_convert('Europe/Berlin')
83+
assert result.index.tz.zone == 'Europe/Berlin'
84+
85+
# can't convert tz-naive
86+
rng = date_range('1/1/2011', periods=200, freq='D')
87+
ts = Series(1, index=rng)
88+
tm.assert_raises_regex(TypeError, "Cannot convert tz-naive",
89+
ts.tz_convert, 'US/Eastern')
90+
91+
# -----------------------------------------------------------------
92+
# Series.append
93+
94+
def test_series_append_aware(self):
95+
rng1 = date_range('1/1/2011 01:00', periods=1, freq='H',
96+
tz='US/Eastern')
97+
rng2 = date_range('1/1/2011 02:00', periods=1, freq='H',
98+
tz='US/Eastern')
99+
ser1 = Series([1], index=rng1)
100+
ser2 = Series([2], index=rng2)
101+
ts_result = ser1.append(ser2)
102+
103+
exp_index = DatetimeIndex(['2011-01-01 01:00', '2011-01-01 02:00'],
104+
tz='US/Eastern')
105+
exp = Series([1, 2], index=exp_index)
106+
tm.assert_series_equal(ts_result, exp)
107+
assert ts_result.index.tz == rng1.tz
108+
109+
rng1 = date_range('1/1/2011 01:00', periods=1, freq='H', tz='UTC')
110+
rng2 = date_range('1/1/2011 02:00', periods=1, freq='H', tz='UTC')
111+
ser1 = Series([1], index=rng1)
112+
ser2 = Series([2], index=rng2)
113+
ts_result = ser1.append(ser2)
114+
115+
exp_index = DatetimeIndex(['2011-01-01 01:00', '2011-01-01 02:00'],
116+
tz='UTC')
117+
exp = Series([1, 2], index=exp_index)
118+
tm.assert_series_equal(ts_result, exp)
119+
utc = rng1.tz
120+
assert utc == ts_result.index.tz
121+
122+
# GH#7795
123+
# different tz coerces to object dtype, not UTC
124+
rng1 = date_range('1/1/2011 01:00', periods=1, freq='H',
125+
tz='US/Eastern')
126+
rng2 = date_range('1/1/2011 02:00', periods=1, freq='H',
127+
tz='US/Central')
128+
ser1 = Series([1], index=rng1)
129+
ser2 = Series([2], index=rng2)
130+
ts_result = ser1.append(ser2)
131+
exp_index = Index([Timestamp('1/1/2011 01:00', tz='US/Eastern'),
132+
Timestamp('1/1/2011 02:00', tz='US/Central')])
133+
exp = Series([1, 2], index=exp_index)
134+
tm.assert_series_equal(ts_result, exp)
135+
136+
def test_series_append_aware_naive(self):
137+
rng1 = date_range('1/1/2011 01:00', periods=1, freq='H')
138+
rng2 = date_range('1/1/2011 02:00', periods=1, freq='H',
139+
tz='US/Eastern')
140+
ser1 = Series(np.random.randn(len(rng1)), index=rng1)
141+
ser2 = Series(np.random.randn(len(rng2)), index=rng2)
142+
ts_result = ser1.append(ser2)
143+
144+
expected = ser1.index.astype(object).append(ser2.index.astype(object))
145+
assert ts_result.index.equals(expected)
146+
147+
# mixed
148+
rng1 = date_range('1/1/2011 01:00', periods=1, freq='H')
149+
rng2 = lrange(100)
150+
ser1 = Series(np.random.randn(len(rng1)), index=rng1)
151+
ser2 = Series(np.random.randn(len(rng2)), index=rng2)
152+
ts_result = ser1.append(ser2)
153+
154+
expected = ser1.index.astype(object).append(ser2.index)
155+
assert ts_result.index.equals(expected)
156+
157+
def test_series_append_dst(self):
158+
rng1 = date_range('1/1/2016 01:00', periods=3, freq='H',
159+
tz='US/Eastern')
160+
rng2 = date_range('8/1/2016 01:00', periods=3, freq='H',
161+
tz='US/Eastern')
162+
ser1 = Series([1, 2, 3], index=rng1)
163+
ser2 = Series([10, 11, 12], index=rng2)
164+
ts_result = ser1.append(ser2)
165+
166+
exp_index = DatetimeIndex(['2016-01-01 01:00', '2016-01-01 02:00',
167+
'2016-01-01 03:00', '2016-08-01 01:00',
168+
'2016-08-01 02:00', '2016-08-01 03:00'],
169+
tz='US/Eastern')
170+
exp = Series([1, 2, 3, 10, 11, 12], index=exp_index)
171+
tm.assert_series_equal(ts_result, exp)
172+
assert ts_result.index.tz == rng1.tz
173+
174+
# -----------------------------------------------------------------
175+
176+
def test_dateutil_tzoffset_support(self):
177+
values = [188.5, 328.25]
178+
tzinfo = tzoffset(None, 7200)
179+
index = [datetime(2012, 5, 11, 11, tzinfo=tzinfo),
180+
datetime(2012, 5, 11, 12, tzinfo=tzinfo)]
181+
series = Series(data=values, index=index)
182+
183+
assert series.index.tz == tzinfo
184+
185+
# it works! #2443
186+
repr(series.index[0])
187+
188+
@pytest.mark.parametrize('tz', ['US/Eastern', 'dateutil/US/Eastern'])
189+
def test_tz_aware_asfreq(self, tz):
190+
dr = date_range('2011-12-01', '2012-07-20', freq='D', tz=tz)
191+
192+
ser = Series(np.random.randn(len(dr)), index=dr)
193+
194+
# it works!
195+
ser.asfreq('T')
196+
197+
@pytest.mark.parametrize('tz', ['US/Eastern', 'dateutil/US/Eastern'])
198+
def test_string_index_alias_tz_aware(self, tz):
199+
rng = date_range('1/1/2000', periods=10, tz=tz)
200+
ser = Series(np.random.randn(len(rng)), index=rng)
201+
202+
result = ser['1/3/2000']
203+
tm.assert_almost_equal(result, ser[2])
204+
205+
# TODO: De-duplicate with test below
206+
def test_series_add_tz_mismatch_converts_to_utc_duplicate(self):
207+
rng = date_range('1/1/2011', periods=10, freq='H', tz='US/Eastern')
208+
ser = Series(np.random.randn(len(rng)), index=rng)
209+
210+
ts_moscow = ser.tz_convert('Europe/Moscow')
211+
212+
result = ser + ts_moscow
213+
assert result.index.tz is pytz.utc
214+
215+
result = ts_moscow + ser
216+
assert result.index.tz is pytz.utc
217+
218+
def test_series_add_tz_mismatch_converts_to_utc(self):
219+
rng = date_range('1/1/2011', periods=100, freq='H', tz='utc')
220+
221+
perm = np.random.permutation(100)[:90]
222+
ser1 = Series(np.random.randn(90),
223+
index=rng.take(perm).tz_convert('US/Eastern'))
224+
225+
perm = np.random.permutation(100)[:90]
226+
ser2 = Series(np.random.randn(90),
227+
index=rng.take(perm).tz_convert('Europe/Berlin'))
228+
229+
result = ser1 + ser2
230+
231+
uts1 = ser1.tz_convert('utc')
232+
uts2 = ser2.tz_convert('utc')
233+
expected = uts1 + uts2
234+
235+
assert result.index.tz == pytz.UTC
236+
tm.assert_series_equal(result, expected)
237+
238+
def test_series_add_aware_naive_raises(self):
239+
rng = date_range('1/1/2011', periods=10, freq='H')
240+
ser = Series(np.random.randn(len(rng)), index=rng)
241+
242+
ser_utc = ser.tz_localize('utc')
243+
244+
with pytest.raises(Exception):
245+
ser + ser_utc
246+
247+
with pytest.raises(Exception):
248+
ser_utc + ser
249+
250+
def test_series_align_aware(self):
251+
idx1 = date_range('2001', periods=5, freq='H', tz='US/Eastern')
252+
ser = Series(np.random.randn(len(idx1)), index=idx1)
253+
ser_central = ser.tz_convert('US/Central')
254+
# # different timezones convert to UTC
255+
256+
new1, new2 = ser.align(ser_central)
257+
assert new1.index.tz == pytz.UTC
258+
assert new2.index.tz == pytz.UTC
259+
260+
@pytest.mark.parametrize('tzstr', ['US/Eastern', 'dateutil/US/Eastern'])
261+
def test_localized_at_time_between_time(self, tzstr):
262+
from datetime import time
263+
tz = timezones.maybe_get_tz(tzstr)
264+
265+
rng = date_range('4/16/2012', '5/1/2012', freq='H')
266+
ts = Series(np.random.randn(len(rng)), index=rng)
267+
268+
ts_local = ts.tz_localize(tzstr)
269+
270+
result = ts_local.at_time(time(10, 0))
271+
expected = ts.at_time(time(10, 0)).tz_localize(tzstr)
272+
tm.assert_series_equal(result, expected)
273+
assert timezones.tz_compare(result.index.tz, tz)
274+
275+
t1, t2 = time(10, 0), time(11, 0)
276+
result = ts_local.between_time(t1, t2)
277+
expected = ts.between_time(t1, t2).tz_localize(tzstr)
278+
tm.assert_series_equal(result, expected)
279+
assert timezones.tz_compare(result.index.tz, tz)
280+
281+
@pytest.mark.parametrize('tzstr', ['Europe/Berlin',
282+
'dateutil/Europe/Berlin'])
283+
def test_getitem_pydatetime_tz(self, tzstr):
284+
tz = timezones.maybe_get_tz(tzstr)
285+
286+
index = date_range(start='2012-12-24 16:00', end='2012-12-24 18:00',
287+
freq='H', tz=tzstr)
288+
ts = Series(index=index, data=index.hour)
289+
time_pandas = Timestamp('2012-12-24 17:00', tz=tzstr)
290+
291+
dt = datetime(2012, 12, 24, 17, 0)
292+
time_datetime = tslib._localize_pydatetime(dt, tz)
293+
assert ts[time_pandas] == ts[time_datetime]

0 commit comments

Comments
 (0)