Skip to content

BUG: Timestamp retains frequency of input Timestamps #23503

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Nov 7, 2018
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions doc/source/whatsnew/v0.24.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,7 @@ Datetimelike
- Bug in :func:`date_range` with frequency of ``Day`` or higher where dates sufficiently far in the future could wrap around to the past instead of raising ``OutOfBoundsDatetime`` (:issue:`14187`)
- Bug in :class:`PeriodIndex` with attribute ``freq.n`` greater than 1 where adding a :class:`DateOffset` object would return incorrect results (:issue:`23215`)
- Bug in :class:`Series` that interpreted string indices as lists of characters when setting datetimelike values (:issue:`23451`)
- Bug in :class:`Timestamp` constructor which would drop the frequency of an input :class:`Timestamp` (:issue:`22311`)

Timedelta
^^^^^^^^^
Expand Down
6 changes: 5 additions & 1 deletion pandas/_libs/tslibs/timestamps.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ from cpython.datetime cimport (datetime,
PyDateTime_IMPORT

from util cimport (is_datetime64_object, is_timedelta64_object,
is_integer_object, is_string_object, is_array)
is_integer_object, is_string_object, is_array,
is_offset_object)

cimport ccalendar
from conversion import tz_localize_to_utc, normalize_i8_timestamps
Expand Down Expand Up @@ -734,6 +735,9 @@ class Timestamp(_Timestamp):

if is_string_object(freq):
freq = to_offset(freq)
elif not is_offset_object(freq):
# GH 22311: Try to extract the frequency of a given Timestamp input
Copy link
Member

Choose a reason for hiding this comment

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

What do we expect it to be in this case? Aside from None I guess

Copy link
Member Author

Choose a reason for hiding this comment

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

This can be a Timestamp in which we want to extract its frequency and pass along.

Copy link
Member

Choose a reason for hiding this comment

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

IIUC you're referring to ts_input being a Timestamp. I'm asking what freq is in this case. More specifically, anything other than None seems like it should be invalid. Or am I missing something?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah sorry for misunderstanding. You're correct in that this is essentially swallowing any nonsense frequency and just returning None

Copy link
Member Author

Choose a reason for hiding this comment

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

freq should only ever be None, a offset string, or offset object

Copy link
Member

Choose a reason for hiding this comment

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

Won't this silently pass if freq has invalid type? Couldn't we just say that freq = getattr(ts_input, 'freq', None) if freq is None else freq?

freq = getattr(ts_input, 'freq', None)

return create_timestamp_from_ts(ts.value, ts.dts, ts.tzinfo, freq)

Expand Down
6 changes: 6 additions & 0 deletions pandas/tests/scalar/timestamp/test_timestamp.py
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,12 @@ def test_construct_with_different_string_format(self, arg):
expected = Timestamp(datetime(2013, 1, 1), tz=pytz.FixedOffset(540))
assert result == expected

def test_construct_timestamp_preserve_original_frequency(self):
# GH 22311
result = Timestamp(Timestamp('2010-08-08', freq='D')).freq
expected = offsets.Day()
assert result == expected


class TestTimestamp(object):

Expand Down