Skip to content

Commit ebe6b91

Browse files
jiangyue12392TomAugspurger
authored andcommitted
BUG: error calculating BusinessHourMixin.apply for long business hour per day (#26381)
* BUG: error calculating BusinessHourMixin.apply for long business hour per day
1 parent 446d306 commit ebe6b91

File tree

3 files changed

+25
-11
lines changed

3 files changed

+25
-11
lines changed

doc/source/whatsnew/v0.25.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ Timedelta
319319

320320
- Bug in :func:`TimedeltaIndex.intersection` where for non-monotonic indices in some cases an empty ``Index`` was returned when in fact an intersection existed (:issue:`25913`)
321321
- Bug with comparisons between :class:`Timedelta` and ``NaT`` raising ``TypeError`` (:issue:`26039`)
322-
-
322+
- Bug when adding or subtracting a :class:`BusinessHour` to a :class:`Timestamp` with the resulting time landing in a following or prior day respectively (:issue:`26381`)
323323

324324
Timezones
325325
^^^^^^^^^

pandas/tests/tseries/offsets/test_offsets.py

+17
Original file line numberDiff line numberDiff line change
@@ -1287,6 +1287,23 @@ def test_opening_time(self, case):
12871287
datetime(2014, 7, 7, 19, 30): datetime(2014, 7, 5, 4, 30),
12881288
datetime(2014, 7, 7, 19, 30, 30): datetime(2014, 7, 5, 4, 30, 30)}))
12891289

1290+
# long business hours (see gh-26381)
1291+
apply_cases.append((BusinessHour(n=4, start='00:00', end='23:00'), {
1292+
datetime(2014, 7, 3, 22): datetime(2014, 7, 4, 3),
1293+
datetime(2014, 7, 4, 22): datetime(2014, 7, 7, 3),
1294+
datetime(2014, 7, 3, 22, 30): datetime(2014, 7, 4, 3, 30),
1295+
datetime(2014, 7, 3, 22, 20): datetime(2014, 7, 4, 3, 20),
1296+
datetime(2014, 7, 4, 22, 30, 30): datetime(2014, 7, 7, 3, 30, 30),
1297+
datetime(2014, 7, 4, 22, 30, 20): datetime(2014, 7, 7, 3, 30, 20)}))
1298+
1299+
apply_cases.append((BusinessHour(n=-4, start='00:00', end='23:00'), {
1300+
datetime(2014, 7, 4, 3): datetime(2014, 7, 3, 22),
1301+
datetime(2014, 7, 7, 3): datetime(2014, 7, 4, 22),
1302+
datetime(2014, 7, 4, 3, 30): datetime(2014, 7, 3, 22, 30),
1303+
datetime(2014, 7, 4, 3, 20): datetime(2014, 7, 3, 22, 20),
1304+
datetime(2014, 7, 7, 3, 30, 30): datetime(2014, 7, 4, 22, 30, 30),
1305+
datetime(2014, 7, 7, 3, 30, 20): datetime(2014, 7, 4, 22, 30, 20)}))
1306+
12901307
@pytest.mark.parametrize('case', apply_cases)
12911308
def test_apply(self, case):
12921309
offset, cases = case

pandas/tseries/offsets.py

+7-10
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,6 @@ def rollforward(self, dt):
689689

690690
@apply_wraps
691691
def apply(self, other):
692-
daytime = self._get_daytime_flag
693692
businesshours = self._get_business_hours_by_sec
694693
bhdelta = timedelta(seconds=businesshours)
695694

@@ -731,21 +730,19 @@ def apply(self, other):
731730
result = other + timedelta(hours=hours, minutes=minutes)
732731

733732
# because of previous adjustment, time will be larger than start
734-
if ((daytime and (result.time() < self.start or
735-
self.end < result.time())) or
736-
not daytime and (self.end < result.time() < self.start)):
737-
if n >= 0:
738-
bday_edge = self._prev_opening_time(other)
739-
bday_edge = bday_edge + bhdelta
740-
# calculate remainder
733+
if n >= 0:
734+
bday_edge = self._prev_opening_time(other) + bhdelta
735+
if bday_edge < result:
741736
bday_remain = result - bday_edge
742737
result = self._next_opening_time(other)
743738
result += bday_remain
744-
else:
745-
bday_edge = self._next_opening_time(other)
739+
else:
740+
bday_edge = self._next_opening_time(other)
741+
if bday_edge > result:
746742
bday_remain = result - bday_edge
747743
result = self._next_opening_time(result) + bhdelta
748744
result += bday_remain
745+
749746
# edge handling
750747
if n >= 0:
751748
if result.time() == self.end:

0 commit comments

Comments
 (0)