Skip to content

Commit bab1995

Browse files
BUG: Fixed ignoring of nanoseconds when adding to series pandas-dev#47856
1 parent 37e6239 commit bab1995

File tree

3 files changed

+31
-4
lines changed

3 files changed

+31
-4
lines changed

doc/source/whatsnew/v1.5.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,7 @@ Datetimelike
824824
- Bug in :meth:`DatetimeIndex.resolution` incorrectly returning "day" instead of "nanosecond" for nanosecond-resolution indexes (:issue:`46903`)
825825
- Bug in :class:`Timestamp` with an integer or float value and ``unit="Y"`` or ``unit="M"`` giving slightly-wrong results (:issue:`47266`)
826826
- Bug in :class:`.DatetimeArray` construction when passed another :class:`.DatetimeArray` and ``freq=None`` incorrectly inferring the freq from the given array (:issue:`47296`)
827+
- Bug in :class:`RelativeDeltaOffset` which caused adding a ``DateOffset`` to a ``Series`` to not add the ``nanoseconds`` field (:issue:`47856`)
827828
-
828829

829830
Timedelta

pandas/_libs/tslibs/offsets.pyx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,8 @@ _relativedelta_kwds = {"years", "months", "weeks", "days", "year", "month",
297297

298298
cdef _determine_offset(kwds):
299299
# timedelta is used for sub-daily plural offsets and all singular
300-
# offsets relativedelta is used for plural offsets of daily length or
301-
# more nanosecond(s) are handled by apply_wraps
300+
# offsets, relativedelta is used for plural offsets of daily length or
301+
# more, nanosecond(s) are handled by apply_wraps
302302
kwds_no_nanos = dict(
303303
(k, v) for k, v in kwds.items()
304304
if k not in ('nanosecond', 'nanoseconds')
@@ -1157,7 +1157,9 @@ cdef class RelativeDeltaOffset(BaseOffset):
11571157
return dt64other
11581158
elif not self._use_relativedelta and hasattr(self, "_offset"):
11591159
# timedelta
1160-
delta = Timedelta(self._offset * self.n)
1160+
num_nano = getattr(self, "nanoseconds", 0)
1161+
rem_nano = Timedelta(nanoseconds=num_nano)
1162+
delta = Timedelta((self._offset + rem_nano) * self.n)
11611163
td = (<_Timedelta>delta)._as_reso(reso)
11621164
return dt64other + td
11631165
else:

pandas/tests/tseries/offsets/test_offsets.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
from pandas import (
3535
DatetimeIndex,
36+
Series,
3637
date_range,
3738
)
3839
import pandas._testing as tm
@@ -987,7 +988,7 @@ def test_dateoffset_add_sub(offset_kwargs, expected_arg):
987988
assert result == expected
988989

989990

990-
def test_dataoffset_add_sub_timestamp_with_nano():
991+
def test_dateoffset_add_sub_timestamp_with_nano():
991992
offset = DateOffset(minutes=2, nanoseconds=9)
992993
ts = Timestamp(4)
993994
result = ts + offset
@@ -1032,3 +1033,26 @@ def test_construct_int_arg_no_kwargs_assumed_days(n):
10321033
result = Timestamp(2022, 1, 2) + offset
10331034
expected = Timestamp(2022, 1, 2 + n)
10341035
assert result == expected
1036+
1037+
1038+
@pytest.mark.parametrize(
1039+
"offset, expected",
1040+
[
1041+
(
1042+
DateOffset(minutes=7, nanoseconds=18),
1043+
Timestamp("2022-01-01 00:07:00.000000018"),
1044+
),
1045+
(DateOffset(nanoseconds=3), Timestamp("2022-01-01 00:00:00.000000003")),
1046+
],
1047+
)
1048+
def test_dateoffset_add_sub_timestamp_series_with_nano(offset, expected):
1049+
# GH 47856
1050+
t = Timestamp("2022-01-01")
1051+
teststamp = t
1052+
s = Series([t])
1053+
s = s + offset
1054+
assert s[0] == expected
1055+
s -= offset
1056+
assert s[0] == teststamp
1057+
s = offset + s
1058+
assert s[0] == expected

0 commit comments

Comments
 (0)