diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst index 690e6b8f725ad..57064bd348aa5 100644 --- a/doc/source/whatsnew/v1.2.0.rst +++ b/doc/source/whatsnew/v1.2.0.rst @@ -412,7 +412,7 @@ Timezones ^^^^^^^^^ - Bug in :func:`date_range` was raising AmbiguousTimeError for valid input with ``ambiguous=False`` (:issue:`35297`) -- +- Bug in :meth:`Timestamp.replace` was losing fold information (:issue:`37610`) Numeric diff --git a/pandas/_libs/tslibs/nattype.pyx b/pandas/_libs/tslibs/nattype.pyx index 88ad008b42c21..e10ac6a05ead8 100644 --- a/pandas/_libs/tslibs/nattype.pyx +++ b/pandas/_libs/tslibs/nattype.pyx @@ -774,7 +774,7 @@ default 'raise' microsecond : int, optional nanosecond : int, optional tzinfo : tz-convertible, optional - fold : int, optional, default is 0 + fold : int, optional Returns ------- diff --git a/pandas/_libs/tslibs/timestamps.pyx b/pandas/_libs/tslibs/timestamps.pyx index 9076325d01bab..b3ae69d7a3237 100644 --- a/pandas/_libs/tslibs/timestamps.pyx +++ b/pandas/_libs/tslibs/timestamps.pyx @@ -1374,7 +1374,7 @@ default 'raise' microsecond=None, nanosecond=None, tzinfo=object, - fold=0, + fold=None, ): """ implements datetime.replace, handles nanoseconds. @@ -1390,7 +1390,7 @@ default 'raise' microsecond : int, optional nanosecond : int, optional tzinfo : tz-convertible, optional - fold : int, optional, default is 0 + fold : int, optional Returns ------- @@ -1407,6 +1407,11 @@ default 'raise' # set to naive if needed tzobj = self.tzinfo value = self.value + + # GH 37610. Preserve fold when replacing. + if fold is None: + fold = self.fold + if tzobj is not None: value = tz_convert_from_utc_single(value, tzobj) diff --git a/pandas/tests/scalar/timestamp/test_unary_ops.py b/pandas/tests/scalar/timestamp/test_unary_ops.py index e8196cd8328e7..88f99a6784ba1 100644 --- a/pandas/tests/scalar/timestamp/test_unary_ops.py +++ b/pandas/tests/scalar/timestamp/test_unary_ops.py @@ -424,3 +424,14 @@ def test_timestamp(self): # should agree with datetime.timestamp method dt = ts.to_pydatetime() assert dt.timestamp() == ts.timestamp() + + +@pytest.mark.parametrize("fold", [0, 1]) +def test_replace_preserves_fold(fold): + # GH 37610. Check that replace preserves Timestamp fold property + tz = gettz("Europe/Moscow") + + ts = Timestamp(year=2009, month=10, day=25, hour=2, minute=30, fold=fold, tzinfo=tz) + ts_replaced = ts.replace(second=1) + + assert ts_replaced.fold == fold