Skip to content

Commit c5566d5

Browse files
committed
BUG: Correctly localize Timestamp near DST
1 parent 415012f commit c5566d5

File tree

4 files changed

+35
-0
lines changed

4 files changed

+35
-0
lines changed

pandas/_libs/tslibs/conversion.pyx

+4
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,10 @@ cdef _TSObject convert_datetime_to_tsobject(datetime ts, object tz,
350350
# sort of a temporary hack
351351
if ts.tzinfo is not None:
352352
if hasattr(tz, 'normalize') and hasattr(ts.tzinfo, '_utcoffset'):
353+
# tz.localize does not correctly localize Timestamps near DST
354+
if hasattr(ts, 'to_pydatetime'):
355+
nanos += ts.nanosecond
356+
ts = ts.to_pydatetime()
353357
ts = tz.normalize(ts)
354358
obj.value = pydatetime_to_dt64(ts, &obj.dts)
355359
obj.tzinfo = ts.tzinfo

pandas/tests/indexes/datetimes/test_construction.py

+9
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,15 @@ def test_constructor_with_non_normalized_pytz(self, tz):
469469
result = DatetimeIndex(['2010'], tz=non_norm_tz)
470470
assert pytz.timezone(tz) is result.tz
471471

472+
def test_constructor_timestamp_near_dst(self):
473+
# GH 20854
474+
ts = [Timestamp('2016-10-30 03:00:00+0300', tz='Europe/Helsinki'),
475+
Timestamp('2016-10-30 03:00:00+0200', tz='Europe/Helsinki')]
476+
result = DatetimeIndex(ts)
477+
expected = DatetimeIndex([ts[0].to_pydatetime(),
478+
ts[1].to_pydatetime()])
479+
tm.assert_index_equal(result, expected)
480+
472481

473482
class TestTimeSeries(object):
474483

pandas/tests/indexes/datetimes/test_date_range.py

+14
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,20 @@ def test_wom_len(self, periods):
278278
res = date_range(start='20110101', periods=periods, freq='WOM-1MON')
279279
assert len(res) == periods
280280

281+
def test_construct_over_dst(self):
282+
# GH 20854
283+
pre_dst = Timestamp('2010-11-07 01:00:00').tz_localize('US/Pacific',
284+
ambiguous=True)
285+
pst_dst = Timestamp('2010-11-07 01:00:00').tz_localize('US/Pacific',
286+
ambiguous=False)
287+
expect_data = [Timestamp('2010-11-07 00:00:00', tz='US/Pacific'),
288+
pre_dst,
289+
pst_dst]
290+
expected = DatetimeIndex(expect_data)
291+
result = date_range(start='2010-11-7', periods=3,
292+
freq='H', tz='US/Pacific')
293+
tm.assert_index_equal(result, expected)
294+
281295

282296
class TestGenRangeGeneration(object):
283297

pandas/tests/scalar/timestamp/test_timestamp.py

+8
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,14 @@ def test_disallow_setting_tz(self, tz):
528528
with pytest.raises(AttributeError):
529529
ts.tz = tz
530530

531+
@pytest.mark.parametrize('offset', ['+0300', '+0200'])
532+
def test_construct_timestamp_near_dst(self, offset):
533+
# GH 20854
534+
expected = Timestamp('2016-10-30 03:00:00{}'.format(offset),
535+
tz='Europe/Helsinki')
536+
result = Timestamp(expected, tz='Europe/Helsinki')
537+
assert result == expected
538+
531539

532540
class TestTimestamp(object):
533541

0 commit comments

Comments
 (0)