Skip to content

Commit 0b49cf3

Browse files
Backport PR #57536 on branch 2.2.x (BUG: dt64 + DateOffset with milliseconds) (#57537)
Backport PR #57536: BUG: dt64 + DateOffset with milliseconds Co-authored-by: Matthew Roeschke <[email protected]>
1 parent 9b1ce06 commit 0b49cf3

File tree

3 files changed

+47
-1
lines changed

3 files changed

+47
-1
lines changed

doc/source/whatsnew/v2.2.1.rst

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ Fixed regressions
4242
- Fixed regression in :meth:`Series.astype` introducing decimals when converting from integer with missing values to string dtype (:issue:`57418`)
4343
- Fixed regression in :meth:`Series.pct_change` raising a ``ValueError`` for an empty :class:`Series` (:issue:`57056`)
4444
- Fixed regression in :meth:`Series.to_numpy` when dtype is given as float and the data contains NaNs (:issue:`57121`)
45+
- Fixed regression in addition or subtraction of :class:`DateOffset` objects with millisecond components to ``datetime64`` :class:`Index`, :class:`Series`, or :class:`DataFrame` (:issue:`57529`)
4546

4647
.. ---------------------------------------------------------------------------
4748
.. _whatsnew_221.bug_fixes:

pandas/_libs/tslibs/offsets.pyx

+14-1
Original file line numberDiff line numberDiff line change
@@ -1458,13 +1458,22 @@ cdef class RelativeDeltaOffset(BaseOffset):
14581458
"minutes",
14591459
"seconds",
14601460
"microseconds",
1461+
"milliseconds",
14611462
}
14621463
# relativedelta/_offset path only valid for base DateOffset
14631464
if self._use_relativedelta and set(kwds).issubset(relativedelta_fast):
1465+
td_args = {
1466+
"days",
1467+
"hours",
1468+
"minutes",
1469+
"seconds",
1470+
"microseconds",
1471+
"milliseconds"
1472+
}
14641473
td_kwds = {
14651474
key: val
14661475
for key, val in kwds.items()
1467-
if key in ["days", "hours", "minutes", "seconds", "microseconds"]
1476+
if key in td_args
14681477
}
14691478
if "weeks" in kwds:
14701479
days = td_kwds.get("days", 0)
@@ -1474,6 +1483,8 @@ cdef class RelativeDeltaOffset(BaseOffset):
14741483
delta = Timedelta(**td_kwds)
14751484
if "microseconds" in kwds:
14761485
delta = delta.as_unit("us")
1486+
elif "milliseconds" in kwds:
1487+
delta = delta.as_unit("ms")
14771488
else:
14781489
delta = delta.as_unit("s")
14791490
else:
@@ -1491,6 +1502,8 @@ cdef class RelativeDeltaOffset(BaseOffset):
14911502
delta = Timedelta(self._offset * self.n)
14921503
if "microseconds" in kwds:
14931504
delta = delta.as_unit("us")
1505+
elif "milliseconds" in kwds:
1506+
delta = delta.as_unit("ms")
14941507
else:
14951508
delta = delta.as_unit("s")
14961509
return delta

pandas/tests/arithmetic/test_datetime64.py

+32
Original file line numberDiff line numberDiff line change
@@ -1586,6 +1586,38 @@ def test_dti_add_sub_nonzero_mth_offset(
15861586
expected = tm.box_expected(expected, box_with_array, False)
15871587
tm.assert_equal(result, expected)
15881588

1589+
def test_dt64arr_series_add_DateOffset_with_milli(self):
1590+
# GH 57529
1591+
dti = DatetimeIndex(
1592+
[
1593+
"2000-01-01 00:00:00.012345678",
1594+
"2000-01-31 00:00:00.012345678",
1595+
"2000-02-29 00:00:00.012345678",
1596+
],
1597+
dtype="datetime64[ns]",
1598+
)
1599+
result = dti + DateOffset(milliseconds=4)
1600+
expected = DatetimeIndex(
1601+
[
1602+
"2000-01-01 00:00:00.016345678",
1603+
"2000-01-31 00:00:00.016345678",
1604+
"2000-02-29 00:00:00.016345678",
1605+
],
1606+
dtype="datetime64[ns]",
1607+
)
1608+
tm.assert_index_equal(result, expected)
1609+
1610+
result = dti + DateOffset(days=1, milliseconds=4)
1611+
expected = DatetimeIndex(
1612+
[
1613+
"2000-01-02 00:00:00.016345678",
1614+
"2000-02-01 00:00:00.016345678",
1615+
"2000-03-01 00:00:00.016345678",
1616+
],
1617+
dtype="datetime64[ns]",
1618+
)
1619+
tm.assert_index_equal(result, expected)
1620+
15891621

15901622
class TestDatetime64OverflowHandling:
15911623
# TODO: box + de-duplicate

0 commit comments

Comments
 (0)