From 91992ad51557053094fad16f7cdab06d57d85cb5 Mon Sep 17 00:00:00 2001 From: Kaiqi Dong Date: Mon, 11 Feb 2019 14:09:35 +0100 Subject: [PATCH] BUG: pandas Timestamp tz_localize and tz_convert do not preserve `freq` attribute (#25247) --- doc/source/whatsnew/v0.25.0.rst | 2 +- pandas/_libs/tslibs/timestamps.pyx | 6 +++--- pandas/tests/indexes/datetimes/test_timezones.py | 7 +++++++ pandas/tests/scalar/timestamp/test_timestamp.py | 7 +++++++ pandas/tests/series/indexing/test_indexing.py | 3 ++- 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/doc/source/whatsnew/v0.25.0.rst b/doc/source/whatsnew/v0.25.0.rst index 1055514cd0e09..95c8d6e2cf6a3 100644 --- a/doc/source/whatsnew/v0.25.0.rst +++ b/doc/source/whatsnew/v0.25.0.rst @@ -95,7 +95,7 @@ Timezones ^^^^^^^^^ - Bug in :func:`to_datetime` with ``utc=True`` and datetime strings that would apply previously parsed UTC offsets to subsequent arguments (:issue:`24992`) -- +- Bug in :func:`Timestamp.tz_localize` and :func:`Timestamp.tz_convert` does not propagate ``freq`` (:issue:`25241`) - Numeric diff --git a/pandas/_libs/tslibs/timestamps.pyx b/pandas/_libs/tslibs/timestamps.pyx index 25b0b4069cf7c..8a95d2494dfa4 100644 --- a/pandas/_libs/tslibs/timestamps.pyx +++ b/pandas/_libs/tslibs/timestamps.pyx @@ -1187,12 +1187,12 @@ class Timestamp(_Timestamp): value = tz_localize_to_utc(np.array([self.value], dtype='i8'), tz, ambiguous=ambiguous, nonexistent=nonexistent)[0] - return Timestamp(value, tz=tz) + return Timestamp(value, tz=tz, freq=self.freq) else: if tz is None: # reset tz value = tz_convert_single(self.value, UTC, self.tz) - return Timestamp(value, tz=None) + return Timestamp(value, tz=tz, freq=self.freq) else: raise TypeError('Cannot localize tz-aware Timestamp, use ' 'tz_convert for conversions') @@ -1222,7 +1222,7 @@ class Timestamp(_Timestamp): 'tz_localize to localize') else: # Same UTC timestamp, different time zone - return Timestamp(self.value, tz=tz) + return Timestamp(self.value, tz=tz, freq=self.freq) astimezone = tz_convert diff --git a/pandas/tests/indexes/datetimes/test_timezones.py b/pandas/tests/indexes/datetimes/test_timezones.py index 12c1b15733895..b25918417efcd 100644 --- a/pandas/tests/indexes/datetimes/test_timezones.py +++ b/pandas/tests/indexes/datetimes/test_timezones.py @@ -825,6 +825,13 @@ def test_dti_drop_dont_lose_tz(self): assert ind.tz is not None + def test_dti_tz_conversion_freq(self, tz_naive_fixture): + # GH25241 + t3 = DatetimeIndex(['2019-01-01 10:00'], freq='H') + assert t3.tz_localize(tz=tz_naive_fixture).freq == t3.freq + t4 = DatetimeIndex(['2019-01-02 12:00'], tz='UTC', freq='T') + assert t4.tz_convert(tz='UTC').freq == t4.freq + def test_drop_dst_boundary(self): # see gh-18031 tz = "Europe/Brussels" diff --git a/pandas/tests/scalar/timestamp/test_timestamp.py b/pandas/tests/scalar/timestamp/test_timestamp.py index b2c05d1564a48..c27ef3d0662c8 100644 --- a/pandas/tests/scalar/timestamp/test_timestamp.py +++ b/pandas/tests/scalar/timestamp/test_timestamp.py @@ -780,6 +780,13 @@ def test_hash_equivalent(self): stamp = Timestamp(datetime(2011, 1, 1)) assert d[stamp] == 5 + def test_tz_conversion_freq(self, tz_naive_fixture): + # GH25241 + t1 = Timestamp('2019-01-01 10:00', freq='H') + assert t1.tz_localize(tz=tz_naive_fixture).freq == t1.freq + t2 = Timestamp('2019-01-02 12:00', tz='UTC', freq='T') + assert t2.tz_convert(tz='UTC').freq == t2.freq + class TestTimestampNsOperations(object): diff --git a/pandas/tests/series/indexing/test_indexing.py b/pandas/tests/series/indexing/test_indexing.py index a5855f68127f4..dbe667a166d0a 100644 --- a/pandas/tests/series/indexing/test_indexing.py +++ b/pandas/tests/series/indexing/test_indexing.py @@ -114,7 +114,8 @@ def test_getitem_get(test_data): # missing d = test_data.ts.index[0] - BDay() - with pytest.raises(KeyError, match=r"Timestamp\('1999-12-31 00:00:00'\)"): + msg = r"Timestamp\('1999-12-31 00:00:00', freq='B'\)" + with pytest.raises(KeyError, match=msg): test_data.ts[d] # None