Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v1.2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion pandas/_libs/tslibs/nattype.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -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
-------
Expand Down
9 changes: 7 additions & 2 deletions pandas/_libs/tslibs/timestamps.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1374,7 +1374,7 @@ default 'raise'
microsecond=None,
nanosecond=None,
tzinfo=object,
fold=0,
fold=None,
):
"""
implements datetime.replace, handles nanoseconds.
Expand All @@ -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
-------
Expand All @@ -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)

Expand Down
11 changes: 11 additions & 0 deletions pandas/tests/scalar/timestamp/test_unary_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -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, tz=tz)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why tz= instead of tzinfo=? I seem to remember that there are vague plans to remove tz= as redundant or something?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tz kwarg allows for a string whereas tzinfo requires a tzinfo object

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But that's not what's happening here...

Copy link
Member Author

@AlexKirko AlexKirko Nov 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, agreed. Passing a tzinfo object into the tz argument gives the same result (as all tzinfo gives us is a Cython type-check before we set tz, tzinfo = tzinfo, None), but passing tzinfo is more readable and doc-compliant.
Changed it, please take a look.

ts_replaced = ts.replace(second=1)

assert ts_replaced.fold == fold