Skip to content

Commit 979c1c6

Browse files
authored
BUG: DTI-datetime_scalar preserve freq (#48818)
* BUG: DTI-datetime_scalar preserve freq * GH ref * add xfail test across DST boundary
1 parent 0dadc71 commit 979c1c6

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

doc/source/whatsnew/v1.6.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ Datetimelike
165165
^^^^^^^^^^^^
166166
- Bug in :func:`pandas.infer_freq`, raising ``TypeError`` when inferred on :class:`RangeIndex` (:issue:`47084`)
167167
- Bug in :class:`DatetimeIndex` constructor failing to raise when ``tz=None`` is explicitly specified in conjunction with timezone-aware ``dtype`` or data (:issue:`48659`)
168+
- Bug in subtracting a ``datetime`` scalar from :class:`DatetimeIndex` failing to retain the original ``freq`` attribute (:issue:`48818`)
168169

169170
Timedelta
170171
^^^^^^^^^

pandas/core/arrays/datetimelike.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -1185,7 +1185,16 @@ def _sub_datetimelike_scalar(self, other: datetime | np.datetime64):
11851185

11861186
i8 = self.asi8
11871187
result = checked_add_with_arr(i8, -other.value, arr_mask=self._isnan)
1188-
return result.view("timedelta64[ns]")
1188+
res_m8 = result.view(f"timedelta64[{self._unit}]")
1189+
1190+
new_freq = None
1191+
if isinstance(self.freq, Tick):
1192+
# adding a scalar preserves freq
1193+
new_freq = self.freq
1194+
1195+
from pandas.core.arrays import TimedeltaArray
1196+
1197+
return TimedeltaArray._simple_new(res_m8, dtype=res_m8.dtype, freq=new_freq)
11891198

11901199
@final
11911200
def _sub_datetime_arraylike(self, other):

pandas/tests/indexes/datetimes/test_datetime.py

+30
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,36 @@
1717

1818

1919
class TestDatetimeIndex:
20+
def test_sub_datetime_preserves_freq(self, tz_naive_fixture):
21+
# GH#48818
22+
dti = date_range("2016-01-01", periods=12, tz=tz_naive_fixture)
23+
24+
res = dti - dti[0]
25+
expected = pd.timedelta_range("0 Days", "11 Days")
26+
tm.assert_index_equal(res, expected)
27+
assert res.freq == expected.freq
28+
29+
@pytest.mark.xfail(
30+
reason="The inherited freq is incorrect bc dti.freq is incorrect "
31+
"https://github.com/pandas-dev/pandas/pull/48818/files#r982793461"
32+
)
33+
def test_sub_datetime_preserves_freq_across_dst(self):
34+
# GH#48818
35+
ts = Timestamp("2016-03-11", tz="US/Pacific")
36+
dti = date_range(ts, periods=4)
37+
38+
res = dti - dti[0]
39+
expected = pd.TimedeltaIndex(
40+
[
41+
pd.Timedelta(days=0),
42+
pd.Timedelta(days=1),
43+
pd.Timedelta(days=2),
44+
pd.Timedelta(days=2, hours=23),
45+
]
46+
)
47+
tm.assert_index_equal(res, expected)
48+
assert res.freq == expected.freq
49+
2050
def test_time_overflow_for_32bit_machines(self):
2151
# GH8943. On some machines NumPy defaults to np.int32 (for example,
2252
# 32-bit Linux machines). In the function _generate_regular_range

0 commit comments

Comments
 (0)