Skip to content

Commit 6d7bd98

Browse files
mroeschkejreback
authored andcommitted
ENH: Support fold argument in Timestamp.replace (pandas-dev#25046)
1 parent 01483d7 commit 6d7bd98

File tree

4 files changed

+26
-9
lines changed

4 files changed

+26
-9
lines changed

doc/source/whatsnew/v0.25.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ including other versions of pandas.
1919
Other Enhancements
2020
^^^^^^^^^^^^^^^^^^
2121

22-
-
22+
- :meth:`Timestamp.replace` now supports the ``fold`` argument to disambiguate DST transition times (:issue:`25017`)
2323
-
2424
-
2525

pandas/_libs/tslibs/nattype.pyx

-1
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,6 @@ class NaTType(_NaT):
669669
nanosecond : int, optional
670670
tzinfo : tz-convertible, optional
671671
fold : int, optional, default is 0
672-
added in 3.6, NotImplemented
673672
674673
Returns
675674
-------

pandas/_libs/tslibs/timestamps.pyx

+11-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# -*- coding: utf-8 -*-
2+
import sys
23
import warnings
34

45
from cpython cimport (PyObject_RichCompareBool, PyObject_RichCompare,
@@ -43,10 +44,11 @@ from pandas._libs.tslibs.timezones import UTC
4344
# Constants
4445
_zero_time = datetime_time(0, 0)
4546
_no_input = object()
46-
47+
PY36 = sys.version_info >= (3, 6)
4748

4849
# ----------------------------------------------------------------------
4950

51+
5052
def maybe_integer_op_deprecated(obj):
5153
# GH#22535 add/sub of integers and int-arrays is deprecated
5254
if obj.freq is not None:
@@ -1195,7 +1197,6 @@ class Timestamp(_Timestamp):
11951197
nanosecond : int, optional
11961198
tzinfo : tz-convertible, optional
11971199
fold : int, optional, default is 0
1198-
added in 3.6, NotImplemented
11991200
12001201
Returns
12011202
-------
@@ -1252,12 +1253,16 @@ class Timestamp(_Timestamp):
12521253
# see GH#18319
12531254
ts_input = _tzinfo.localize(datetime(dts.year, dts.month, dts.day,
12541255
dts.hour, dts.min, dts.sec,
1255-
dts.us))
1256+
dts.us),
1257+
is_dst=not bool(fold))
12561258
_tzinfo = ts_input.tzinfo
12571259
else:
1258-
ts_input = datetime(dts.year, dts.month, dts.day,
1259-
dts.hour, dts.min, dts.sec, dts.us,
1260-
tzinfo=_tzinfo)
1260+
kwargs = {'year': dts.year, 'month': dts.month, 'day': dts.day,
1261+
'hour': dts.hour, 'minute': dts.min, 'second': dts.sec,
1262+
'microsecond': dts.us, 'tzinfo': _tzinfo}
1263+
if PY36:
1264+
kwargs['fold'] = fold
1265+
ts_input = datetime(**kwargs)
12611266

12621267
ts = convert_datetime_to_tsobject(ts_input, _tzinfo)
12631268
value = ts.value + (dts.ps // 1000)

pandas/tests/scalar/timestamp/test_unary_ops.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from pandas._libs.tslibs import conversion
1010
from pandas._libs.tslibs.frequencies import INVALID_FREQ_ERR_MSG
11-
from pandas.compat import PY3
11+
from pandas.compat import PY3, PY36
1212
import pandas.util._test_decorators as td
1313

1414
from pandas import NaT, Timestamp
@@ -329,6 +329,19 @@ def test_replace_dst_border(self):
329329
expected = Timestamp('2013-11-3 03:00:00', tz='America/Chicago')
330330
assert result == expected
331331

332+
@pytest.mark.skipif(not PY36, reason='Fold not available until PY3.6')
333+
@pytest.mark.parametrize('fold', [0, 1])
334+
@pytest.mark.parametrize('tz', ['dateutil/Europe/London', 'Europe/London'])
335+
def test_replace_dst_fold(self, fold, tz):
336+
# GH 25017
337+
d = datetime(2019, 10, 27, 2, 30)
338+
ts = Timestamp(d, tz=tz)
339+
result = ts.replace(hour=1, fold=fold)
340+
expected = Timestamp(datetime(2019, 10, 27, 1, 30)).tz_localize(
341+
tz, ambiguous=not fold
342+
)
343+
assert result == expected
344+
332345
# --------------------------------------------------------------
333346
# Timestamp.normalize
334347

0 commit comments

Comments
 (0)