Skip to content

Commit cffe6f2

Browse files
sinhrksjreback
authored andcommitted
BUG: DatetimeTz shift raises AmbiguousTimeError near DST
xref #13650 ``` Author: sinhrks <[email protected]> Closes #13926 from sinhrks/dttz_shift_dst and squashes the following commits: c079ee3 [sinhrks] BUG: DatetimeTz shift raises AmbiguousTimeError near DST
1 parent 55a0c2e commit cffe6f2

File tree

3 files changed

+31
-4
lines changed

3 files changed

+31
-4
lines changed

doc/source/whatsnew/v0.19.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,7 @@ Bug Fixes
875875
- Clean some compile time warnings in datetime parsing (:issue:`13607`)
876876
- Bug in ``factorize`` raises ``AmbiguousTimeError`` if data contains datetime near DST boundary (:issue:`13750`)
877877
- Bug in ``.set_index`` raises ``AmbiguousTimeError`` if new index contains DST boundary and multi levels (:issue:`12920`)
878+
- Bug in ``.shift`` raises ``AmbiguousTimeError`` if data contains datetime near DST boundary (:issue:`13926`)
878879
- Bug in ``pd.read_hdf()`` returns incorrect result when a ``DataFrame`` with a ``categorical`` column and a query which doesn't match any values (:issue:`13792`)
879880
- Bug in ``pd.to_datetime()`` raise ``AttributeError`` with NaN and the other string is not valid when errors='ignore' (:issue:`12424`)
880881

pandas/core/internals.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -2438,15 +2438,14 @@ def shift(self, periods, axis=0, mgr=None):
24382438
else:
24392439
indexer[:periods] = np.arange(-periods, N)
24402440

2441-
# move to UTC & take
2442-
new_values = self.values.tz_localize(None).asi8.take(indexer)
2441+
new_values = self.values.asi8.take(indexer)
24432442

24442443
if periods > 0:
24452444
new_values[:periods] = tslib.iNaT
24462445
else:
24472446
new_values[periods:] = tslib.iNaT
24482447

2449-
new_values = DatetimeIndex(new_values, tz=self.values.tz)
2448+
new_values = self.values._shallow_copy(new_values)
24502449
return [self.make_block_same_class(new_values,
24512450
placement=self.mgr_locs)]
24522451

pandas/tests/series/test_timeseries.py

+28-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import numpy as np
77

8-
from pandas import Index, Series, date_range
8+
from pandas import Index, Series, date_range, NaT
99
from pandas.tseries.index import DatetimeIndex
1010
from pandas.tseries.tdi import TimedeltaIndex
1111

@@ -93,6 +93,33 @@ def test_shift(self):
9393
tz='CET'), name='foo')
9494
self.assertRaises(ValueError, lambda: s - s2)
9595

96+
def test_shift_dst(self):
97+
# GH 13926
98+
dates = date_range('2016-11-06', freq='H', periods=10, tz='US/Eastern')
99+
s = Series(dates)
100+
101+
res = s.shift(0)
102+
tm.assert_series_equal(res, s)
103+
self.assertEqual(res.dtype, 'datetime64[ns, US/Eastern]')
104+
105+
res = s.shift(1)
106+
exp_vals = [NaT] + dates.asobject.values.tolist()[:9]
107+
exp = Series(exp_vals)
108+
tm.assert_series_equal(res, exp)
109+
self.assertEqual(res.dtype, 'datetime64[ns, US/Eastern]')
110+
111+
res = s.shift(-2)
112+
exp_vals = dates.asobject.values.tolist()[2:] + [NaT, NaT]
113+
exp = Series(exp_vals)
114+
tm.assert_series_equal(res, exp)
115+
self.assertEqual(res.dtype, 'datetime64[ns, US/Eastern]')
116+
117+
for ex in [10, -10, 20, -20]:
118+
res = s.shift(ex)
119+
exp = Series([NaT] * 10, dtype='datetime64[ns, US/Eastern]')
120+
tm.assert_series_equal(res, exp)
121+
self.assertEqual(res.dtype, 'datetime64[ns, US/Eastern]')
122+
96123
def test_tshift(self):
97124
# PeriodIndex
98125
ps = tm.makePeriodSeries()

0 commit comments

Comments
 (0)