diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst index 7c850ffedfcab..281edf1834fb2 100644 --- a/doc/source/whatsnew/v1.2.0.rst +++ b/doc/source/whatsnew/v1.2.0.rst @@ -390,6 +390,7 @@ Datetimelike - Bug in :meth:`DatetimeIndex.equals` and :meth:`TimedeltaIndex.equals` incorrectly considering ``int64`` indexes as equal (:issue:`36744`) - Bug in :meth:`TimedeltaIndex.sum` and :meth:`Series.sum` with ``timedelta64`` dtype on an empty index or series returning ``NaT`` instead of ``Timedelta(0)`` (:issue:`31751`) - Bug in :meth:`DatetimeArray.shift` incorrectly allowing ``fill_value`` with a mismatched timezone (:issue:`37299`) +- Bug in adding a :class:`BusinessDay` with nonzero ``offset`` to a non-scalar other (:issue:`37457`) Timedelta ^^^^^^^^^ diff --git a/pandas/_libs/tslibs/offsets.pyx b/pandas/_libs/tslibs/offsets.pyx index 98b2ddbd21ee1..dbd094905cf24 100644 --- a/pandas/_libs/tslibs/offsets.pyx +++ b/pandas/_libs/tslibs/offsets.pyx @@ -1388,7 +1388,11 @@ cdef class BusinessDay(BusinessMixin): @apply_array_wraps def _apply_array(self, dtarr): i8other = dtarr.view("i8") - return shift_bdays(i8other, self.n) + res = _shift_bdays(i8other, self.n) + if self.offset: + res = res.view("M8[ns]") + Timedelta(self.offset) + res = res.view("i8") + return res def is_on_offset(self, dt: datetime) -> bool: if self.normalize and not _is_normalized(dt): @@ -3778,7 +3782,7 @@ cdef inline void _shift_quarters(const int64_t[:] dtindex, out[i] = dtstruct_to_dt64(&dts) -cdef ndarray[int64_t] shift_bdays(const int64_t[:] i8other, int periods): +cdef ndarray[int64_t] _shift_bdays(const int64_t[:] i8other, int periods): """ Implementation of BusinessDay.apply_offset. diff --git a/pandas/tests/tseries/offsets/test_offsets.py b/pandas/tests/tseries/offsets/test_offsets.py index 922aff1792227..fba123e47feb2 100644 --- a/pandas/tests/tseries/offsets/test_offsets.py +++ b/pandas/tests/tseries/offsets/test_offsets.py @@ -750,6 +750,13 @@ def test_with_offset(self): assert (self.d + offset) == datetime(2008, 1, 2, 2) + def test_with_offset_index(self): + dti = DatetimeIndex([self.d]) + result = dti + (self.offset + timedelta(hours=2)) + + expected = DatetimeIndex([datetime(2008, 1, 2, 2)]) + tm.assert_index_equal(result, expected) + def test_eq(self): assert self.offset2 == self.offset2 @@ -2642,6 +2649,13 @@ def test_with_offset(self): assert (self.d + offset) == datetime(2008, 1, 2, 2) + def test_with_offset_index(self): + dti = DatetimeIndex([self.d]) + result = dti + (self.offset + timedelta(hours=2)) + + expected = DatetimeIndex([datetime(2008, 1, 2, 2)]) + tm.assert_index_equal(result, expected) + def test_eq(self): assert self.offset2 == self.offset2