Skip to content

Commit a44f1c1

Browse files
jbrockmendeljreback
authored andcommitted
split Timestamp tests off of 19504 (pandas-dev#19511)
1 parent 58f2a4c commit a44f1c1

File tree

2 files changed

+190
-194
lines changed

2 files changed

+190
-194
lines changed

pandas/tests/scalar/timestamp/test_timezones.py

+189
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,41 @@
22
"""
33
Tests for Timestamp timezone-related methods
44
"""
5+
from datetime import date, timedelta
56

7+
from distutils.version import LooseVersion
68
import pytest
9+
import pytz
710
from pytz.exceptions import AmbiguousTimeError, NonExistentTimeError
11+
import dateutil
12+
from dateutil.tz import gettz, tzoffset
813

914
import pandas.util.testing as tm
15+
import pandas.util._test_decorators as td
16+
1017
from pandas import Timestamp, NaT
1118

1219

1320
class TestTimestampTZOperations(object):
1421
# --------------------------------------------------------------
1522
# Timestamp.tz_localize
1623

24+
def test_tz_localize_ambiguous_bool(self):
25+
# make sure that we are correctly accepting bool values as ambiguous
26+
# GH#14402
27+
ts = Timestamp('2015-11-01 01:00:03')
28+
expected0 = Timestamp('2015-11-01 01:00:03-0500', tz='US/Central')
29+
expected1 = Timestamp('2015-11-01 01:00:03-0600', tz='US/Central')
30+
31+
with pytest.raises(pytz.AmbiguousTimeError):
32+
ts.tz_localize('US/Central')
33+
34+
result = ts.tz_localize('US/Central', ambiguous=True)
35+
assert result == expected0
36+
37+
result = ts.tz_localize('US/Central', ambiguous=False)
38+
assert result == expected1
39+
1740
def test_tz_localize_ambiguous(self):
1841
ts = Timestamp('2014-11-02 01:00')
1942
ts_dst = ts.tz_localize('US/Eastern', ambiguous=True)
@@ -70,6 +93,55 @@ def test_tz_localize_roundtrip(self, stamp, tz):
7093
assert reset == ts
7194
assert reset.tzinfo is None
7295

96+
def test_tz_localize_ambiguous_compat(self):
97+
# validate that pytz and dateutil are compat for dst
98+
# when the transition happens
99+
naive = Timestamp('2013-10-27 01:00:00')
100+
101+
pytz_zone = 'Europe/London'
102+
dateutil_zone = 'dateutil/Europe/London'
103+
result_pytz = naive.tz_localize(pytz_zone, ambiguous=0)
104+
result_dateutil = naive.tz_localize(dateutil_zone, ambiguous=0)
105+
assert result_pytz.value == result_dateutil.value
106+
assert result_pytz.value == 1382835600000000000
107+
108+
if LooseVersion(dateutil.__version__) < LooseVersion('2.6.0'):
109+
# dateutil 2.6 buggy w.r.t. ambiguous=0
110+
# see gh-14621
111+
# see https://github.com/dateutil/dateutil/issues/321
112+
assert (result_pytz.to_pydatetime().tzname() ==
113+
result_dateutil.to_pydatetime().tzname())
114+
assert str(result_pytz) == str(result_dateutil)
115+
elif LooseVersion(dateutil.__version__) > LooseVersion('2.6.0'):
116+
# fixed ambiguous behavior
117+
assert result_pytz.to_pydatetime().tzname() == 'GMT'
118+
assert result_dateutil.to_pydatetime().tzname() == 'BST'
119+
assert str(result_pytz) != str(result_dateutil)
120+
121+
# 1 hour difference
122+
result_pytz = naive.tz_localize(pytz_zone, ambiguous=1)
123+
result_dateutil = naive.tz_localize(dateutil_zone, ambiguous=1)
124+
assert result_pytz.value == result_dateutil.value
125+
assert result_pytz.value == 1382832000000000000
126+
127+
# dateutil < 2.6 is buggy w.r.t. ambiguous timezones
128+
if LooseVersion(dateutil.__version__) > LooseVersion('2.5.3'):
129+
# see gh-14621
130+
assert str(result_pytz) == str(result_dateutil)
131+
assert (result_pytz.to_pydatetime().tzname() ==
132+
result_dateutil.to_pydatetime().tzname())
133+
134+
@pytest.mark.parametrize('tz', [pytz.timezone('US/Eastern'),
135+
gettz('US/Eastern'),
136+
'US/Eastern', 'dateutil/US/Eastern'])
137+
def test_timestamp_tz_localize(self, tz):
138+
stamp = Timestamp('3/11/2012 04:00')
139+
140+
result = stamp.tz_localize(tz)
141+
expected = Timestamp('3/11/2012 04:00', tz=tz)
142+
assert result.hour == expected.hour
143+
assert result == expected
144+
73145
# ------------------------------------------------------------------
74146
# Timestamp.tz_convert
75147

@@ -85,3 +157,120 @@ def test_tz_convert_roundtrip(self, stamp, tz):
85157
assert reset == Timestamp(stamp)
86158
assert reset.tzinfo is None
87159
assert reset == converted.tz_convert('UTC').tz_localize(None)
160+
161+
@pytest.mark.parametrize('tzstr', ['US/Eastern', 'dateutil/US/Eastern'])
162+
def test_astimezone(self, tzstr):
163+
# astimezone is an alias for tz_convert, so keep it with
164+
# the tz_convert tests
165+
utcdate = Timestamp('3/11/2012 22:00', tz='UTC')
166+
expected = utcdate.tz_convert(tzstr)
167+
result = utcdate.astimezone(tzstr)
168+
assert expected == result
169+
assert isinstance(result, Timestamp)
170+
171+
@td.skip_if_windows
172+
def test_tz_convert_utc_with_system_utc(self):
173+
from pandas._libs.tslibs.timezones import maybe_get_tz
174+
175+
# from system utc to real utc
176+
ts = Timestamp('2001-01-05 11:56', tz=maybe_get_tz('dateutil/UTC'))
177+
# check that the time hasn't changed.
178+
assert ts == ts.tz_convert(dateutil.tz.tzutc())
179+
180+
# from system utc to real utc
181+
ts = Timestamp('2001-01-05 11:56', tz=maybe_get_tz('dateutil/UTC'))
182+
# check that the time hasn't changed.
183+
assert ts == ts.tz_convert(dateutil.tz.tzutc())
184+
185+
# ------------------------------------------------------------------
186+
# Timestamp.__init__ with tz str or tzinfo
187+
188+
def test_timestamp_constructor_tz_utc(self):
189+
utc_stamp = Timestamp('3/11/2012 05:00', tz='utc')
190+
assert utc_stamp.tzinfo is pytz.utc
191+
assert utc_stamp.hour == 5
192+
193+
utc_stamp = Timestamp('3/11/2012 05:00').tz_localize('utc')
194+
assert utc_stamp.hour == 5
195+
196+
def test_timestamp_to_datetime_tzoffset(self):
197+
tzinfo = tzoffset(None, 7200)
198+
expected = Timestamp('3/11/2012 04:00', tz=tzinfo)
199+
result = Timestamp(expected.to_pydatetime())
200+
assert expected == result
201+
202+
def test_timestamp_constructor_near_dst_boundary(self):
203+
# GH#11481 & GH#15777
204+
# Naive string timestamps were being localized incorrectly
205+
# with tz_convert_single instead of tz_localize_to_utc
206+
207+
for tz in ['Europe/Brussels', 'Europe/Prague']:
208+
result = Timestamp('2015-10-25 01:00', tz=tz)
209+
expected = Timestamp('2015-10-25 01:00').tz_localize(tz)
210+
assert result == expected
211+
212+
with pytest.raises(pytz.AmbiguousTimeError):
213+
Timestamp('2015-10-25 02:00', tz=tz)
214+
215+
result = Timestamp('2017-03-26 01:00', tz='Europe/Paris')
216+
expected = Timestamp('2017-03-26 01:00').tz_localize('Europe/Paris')
217+
assert result == expected
218+
219+
with pytest.raises(pytz.NonExistentTimeError):
220+
Timestamp('2017-03-26 02:00', tz='Europe/Paris')
221+
222+
# GH#11708
223+
naive = Timestamp('2015-11-18 10:00:00')
224+
result = naive.tz_localize('UTC').tz_convert('Asia/Kolkata')
225+
expected = Timestamp('2015-11-18 15:30:00+0530', tz='Asia/Kolkata')
226+
assert result == expected
227+
228+
# GH#15823
229+
result = Timestamp('2017-03-26 00:00', tz='Europe/Paris')
230+
expected = Timestamp('2017-03-26 00:00:00+0100', tz='Europe/Paris')
231+
assert result == expected
232+
233+
result = Timestamp('2017-03-26 01:00', tz='Europe/Paris')
234+
expected = Timestamp('2017-03-26 01:00:00+0100', tz='Europe/Paris')
235+
assert result == expected
236+
237+
with pytest.raises(pytz.NonExistentTimeError):
238+
Timestamp('2017-03-26 02:00', tz='Europe/Paris')
239+
240+
result = Timestamp('2017-03-26 02:00:00+0100', tz='Europe/Paris')
241+
naive = Timestamp(result.value)
242+
expected = naive.tz_localize('UTC').tz_convert('Europe/Paris')
243+
assert result == expected
244+
245+
result = Timestamp('2017-03-26 03:00', tz='Europe/Paris')
246+
expected = Timestamp('2017-03-26 03:00:00+0200', tz='Europe/Paris')
247+
assert result == expected
248+
249+
@pytest.mark.parametrize('tz', [pytz.timezone('US/Eastern'),
250+
gettz('US/Eastern'),
251+
'US/Eastern', 'dateutil/US/Eastern'])
252+
def test_timestamp_constructed_by_date_and_tz(self, tz):
253+
# GH#2993, Timestamp cannot be constructed by datetime.date
254+
# and tz correctly
255+
256+
result = Timestamp(date(2012, 3, 11), tz=tz)
257+
258+
expected = Timestamp('3/11/2012', tz=tz)
259+
assert result.hour == expected.hour
260+
assert result == expected
261+
262+
@pytest.mark.parametrize('tz', [pytz.timezone('US/Eastern'),
263+
gettz('US/Eastern'),
264+
'US/Eastern', 'dateutil/US/Eastern'])
265+
def test_timestamp_add_timedelta_push_over_dst_boundary(self, tz):
266+
# GH#1389
267+
268+
# 4 hours before DST transition
269+
stamp = Timestamp('3/10/2012 22:00', tz=tz)
270+
271+
result = stamp + timedelta(hours=6)
272+
273+
# spring forward, + "7" hours
274+
expected = Timestamp('3/11/2012 05:00', tz=tz)
275+
276+
assert result == expected

0 commit comments

Comments
 (0)