Skip to content

Commit 63f0b52

Browse files
Si Wei HowSi Wei How
Si Wei How
authored and
Si Wei How
committed
Support multiple starting and ending times in BusinessHour
1 parent ecfc92e commit 63f0b52

File tree

3 files changed

+408
-83
lines changed

3 files changed

+408
-83
lines changed

doc/source/whatsnew/v0.25.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ Other Enhancements
8282
- :meth:`DataFrame.query` and :meth:`DataFrame.eval` now supports quoting column names with backticks to refer to names with spaces (:issue:`6508`)
8383
- :func:`merge_asof` now gives a more clear error message when merge keys are categoricals that are not equal (:issue:`26136`)
8484
- :meth:`pandas.core.window.Rolling` supports exponential (or Poisson) window type (:issue:`21303`)
85-
-
85+
- :class: `pandas.offsets.BusinessHour` supports multiple opening hours intervals
8686

8787
.. _whatsnew_0250.api_breaking:
8888

pandas/tests/tseries/offsets/test_offsets.py

+258-2
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,12 @@ def setup_method(self, method):
760760
self.offset6 = BusinessHour(start='20:00', end='05:00')
761761
self.offset7 = BusinessHour(n=-2, start=dt_time(21, 30),
762762
end=dt_time(6, 30))
763+
self.offset8 = BusinessHour(start=['09:00', '13:00'],
764+
end=['12:00', '17:00'])
765+
self.offset9 = BusinessHour(n=3, start=['09:00', '22:00'],
766+
end=['13:00', '03:00'])
767+
self.offset10 = BusinessHour(n=-1, start=['23:00', '13:00'],
768+
end=['02:00', '17:00'])
763769

764770
def test_constructor_errors(self):
765771
from datetime import time as dt_time
@@ -769,6 +775,14 @@ def test_constructor_errors(self):
769775
BusinessHour(start='AAA')
770776
with pytest.raises(ValueError):
771777
BusinessHour(start='14:00:05')
778+
with pytest.raises(ValueError):
779+
BusinessHour(start=[])
780+
with pytest.raises(ValueError):
781+
BusinessHour(start=['09:00', '11:00'])
782+
with pytest.raises(ValueError):
783+
BusinessHour(start=['09:00', '11:00'], end=['10:00'])
784+
with pytest.raises(ValueError):
785+
BusinessHour(start=['09:00', '11:00'], end=['12:00', '20:00'])
772786

773787
def test_different_normalize_equals(self):
774788
# GH#21404 changed __eq__ to return False when `normalize` doesnt match
@@ -785,6 +799,12 @@ def test_repr(self):
785799
assert repr(self.offset5) == '<BusinessHour: BH=11:00-14:30>'
786800
assert repr(self.offset6) == '<BusinessHour: BH=20:00-05:00>'
787801
assert repr(self.offset7) == '<-2 * BusinessHours: BH=21:30-06:30>'
802+
assert (repr(self.offset8) ==
803+
'<BusinessHour: BH=09:00-12:00,13:00-17:00>')
804+
assert (repr(self.offset9) ==
805+
'<3 * BusinessHours: BH=09:00-13:00,22:00-03:00>')
806+
assert (repr(self.offset10) ==
807+
'<-1 * BusinessHour: BH=13:00-17:00,23:00-02:00>')
788808

789809
def test_with_offset(self):
790810
expected = Timestamp('2014-07-01 13:00')
@@ -793,7 +813,8 @@ def test_with_offset(self):
793813
assert self.d + BusinessHour(n=3) == expected
794814

795815
def test_eq(self):
796-
for offset in [self.offset1, self.offset2, self.offset3, self.offset4]:
816+
for offset in [self.offset1, self.offset2, self.offset3, self.offset4,
817+
self.offset8, self.offset9, self.offset10]:
797818
assert offset == offset
798819

799820
assert BusinessHour() != BusinessHour(-1)
@@ -802,15 +823,28 @@ def test_eq(self):
802823
assert (BusinessHour(start='09:00', end='17:00') !=
803824
BusinessHour(start='17:00', end='09:01'))
804825

826+
assert (BusinessHour(start=['23:00', '13:00'],
827+
end=['12:00', '17:00']) ==
828+
BusinessHour(start=['13:00', '23:00'],
829+
end=['17:00', '12:00']))
830+
assert (BusinessHour(start=['13:00', '23:00'],
831+
end=['18:00', '07:00']) !=
832+
BusinessHour(start=['13:00', '23:00'],
833+
end=['17:00', '12:00']))
834+
805835
def test_hash(self):
806-
for offset in [self.offset1, self.offset2, self.offset3, self.offset4]:
836+
for offset in [self.offset1, self.offset2, self.offset3, self.offset4,
837+
self.offset8, self.offset9, self.offset10]:
807838
assert hash(offset) == hash(offset)
808839

809840
def test_call(self):
810841
assert self.offset1(self.d) == datetime(2014, 7, 1, 11)
811842
assert self.offset2(self.d) == datetime(2014, 7, 1, 13)
812843
assert self.offset3(self.d) == datetime(2014, 6, 30, 17)
813844
assert self.offset4(self.d) == datetime(2014, 6, 30, 14)
845+
assert self.offset8(self.d) == datetime(2014, 7, 1, 11)
846+
assert self.offset9(self.d) == datetime(2014, 7, 1, 22)
847+
assert self.offset10(self.d) == datetime(2014, 7, 1, 1)
814848

815849
def test_sub(self):
816850
# we have to override test_sub here becasue self.offset2 is not
@@ -831,6 +865,9 @@ def testRollback1(self):
831865
assert self.offset5.rollback(self.d) == datetime(2014, 6, 30, 14, 30)
832866
assert self.offset6.rollback(self.d) == datetime(2014, 7, 1, 5, 0)
833867
assert self.offset7.rollback(self.d) == datetime(2014, 7, 1, 6, 30)
868+
assert self.offset8.rollback(self.d) == self.d
869+
assert self.offset9.rollback(self.d) == self.d
870+
assert self.offset10.rollback(self.d) == datetime(2014, 7, 1, 2)
834871

835872
d = datetime(2014, 7, 1, 0)
836873
assert self.offset1.rollback(d) == datetime(2014, 6, 30, 17)
@@ -840,6 +877,9 @@ def testRollback1(self):
840877
assert self.offset5.rollback(d) == datetime(2014, 6, 30, 14, 30)
841878
assert self.offset6.rollback(d) == d
842879
assert self.offset7.rollback(d) == d
880+
assert self.offset8.rollback(d) == datetime(2014, 6, 30, 17)
881+
assert self.offset9.rollback(d) == d
882+
assert self.offset10.rollback(d) == d
843883

844884
assert self._offset(5).rollback(self.d) == self.d
845885

@@ -858,6 +898,9 @@ def testRollforward1(self):
858898
datetime(2014, 7, 1, 20, 0))
859899
assert (self.offset7.rollforward(self.d) ==
860900
datetime(2014, 7, 1, 21, 30))
901+
assert self.offset8.rollforward(self.d) == self.d
902+
assert self.offset9.rollforward(self.d) == self.d
903+
assert self.offset10.rollforward(self.d) == datetime(2014, 7, 1, 13)
861904

862905
d = datetime(2014, 7, 1, 0)
863906
assert self.offset1.rollforward(d) == datetime(2014, 7, 1, 9)
@@ -867,6 +910,9 @@ def testRollforward1(self):
867910
assert self.offset5.rollforward(d) == datetime(2014, 7, 1, 11)
868911
assert self.offset6.rollforward(d) == d
869912
assert self.offset7.rollforward(d) == d
913+
assert self.offset8.rollforward(d) == datetime(2014, 7, 1, 9)
914+
assert self.offset9.rollforward(d) == d
915+
assert self.offset10.rollforward(d) == d
870916

871917
assert self._offset(5).rollforward(self.d) == self.d
872918

@@ -961,6 +1007,35 @@ def test_normalize(self, case):
9611007
datetime(2014, 7, 6, 23, 0): False,
9621008
datetime(2014, 7, 7, 3, 0): False}))
9631009

1010+
on_offset_cases.append((BusinessHour(start=['09:00', '13:00'],
1011+
end=['12:00', '17:00']), {
1012+
datetime(2014, 7, 1, 9): True,
1013+
datetime(2014, 7, 1, 8, 59): False,
1014+
datetime(2014, 7, 1, 8): False,
1015+
datetime(2014, 7, 1, 17): True,
1016+
datetime(2014, 7, 1, 17, 1): False,
1017+
datetime(2014, 7, 1, 18): False,
1018+
datetime(2014, 7, 5, 9): False,
1019+
datetime(2014, 7, 6, 12): False,
1020+
datetime(2014, 7, 1, 12, 30): False}))
1021+
1022+
on_offset_cases.append((BusinessHour(start=['19:00', '23:00'],
1023+
end=['21:00', '05:00']), {
1024+
datetime(2014, 7, 1, 9, 0): False,
1025+
datetime(2014, 7, 1, 10, 0): False,
1026+
datetime(2014, 7, 1, 15): False,
1027+
datetime(2014, 7, 1, 15, 1): False,
1028+
datetime(2014, 7, 5, 12, 0): False,
1029+
datetime(2014, 7, 6, 12, 0): False,
1030+
datetime(2014, 7, 1, 19, 0): True,
1031+
datetime(2014, 7, 2, 0, 0): True,
1032+
datetime(2014, 7, 4, 23): True,
1033+
datetime(2014, 7, 5, 1): True,
1034+
datetime(2014, 7, 5, 5, 0): True,
1035+
datetime(2014, 7, 6, 23, 0): False,
1036+
datetime(2014, 7, 7, 3, 0): False,
1037+
datetime(2014, 7, 4, 22): False}))
1038+
9641039
@pytest.mark.parametrize('case', on_offset_cases)
9651040
def test_onOffset(self, case):
9661041
offset, cases = case
@@ -1126,6 +1201,76 @@ def test_onOffset(self, case):
11261201
datetime(2014, 7, 7, 18): (datetime(2014, 7, 7, 17),
11271202
datetime(2014, 7, 8, 17))}))
11281203

1204+
opening_time_cases.append(([BusinessHour(start=['11:15', '15:00'],
1205+
end=['13:00', '20:00']),
1206+
BusinessHour(n=3, start=['11:15', '15:00'],
1207+
end=['12:00', '20:00']),
1208+
BusinessHour(start=['11:15', '15:00'],
1209+
end=['13:00', '17:00']),
1210+
BusinessHour(n=2, start=['11:15', '15:00'],
1211+
end=['12:00', '03:00']),
1212+
BusinessHour(n=3, start=['11:15', '15:00'],
1213+
end=['13:00', '16:00'])], {
1214+
datetime(2014, 7, 1, 11): (datetime(2014, 7, 1, 11, 15),
1215+
datetime(2014, 6, 30, 15)),
1216+
datetime(2014, 7, 1, 18): (datetime(2014, 7, 2, 11, 15),
1217+
datetime(2014, 7, 1, 15)),
1218+
datetime(2014, 7, 1, 23): (datetime(2014, 7, 2, 11, 15),
1219+
datetime(2014, 7, 1, 15)),
1220+
datetime(2014, 7, 2, 8): (datetime(2014, 7, 2, 11, 15),
1221+
datetime(2014, 7, 1, 15)),
1222+
datetime(2014, 7, 2, 9): (datetime(2014, 7, 2, 11, 15),
1223+
datetime(2014, 7, 1, 15)),
1224+
datetime(2014, 7, 2, 10): (datetime(2014, 7, 2, 11, 15),
1225+
datetime(2014, 7, 1, 15)),
1226+
datetime(2014, 7, 2, 11, 15): (datetime(2014, 7, 2, 11, 15),
1227+
datetime(2014, 7, 2, 11, 15)),
1228+
datetime(2014, 7, 2, 11, 15, 1): (datetime(2014, 7, 2, 15),
1229+
datetime(2014, 7, 2, 11, 15)),
1230+
datetime(2014, 7, 5, 10): (datetime(2014, 7, 7, 11, 15),
1231+
datetime(2014, 7, 4, 15)),
1232+
datetime(2014, 7, 4, 10): (datetime(2014, 7, 4, 11, 15),
1233+
datetime(2014, 7, 3, 15)),
1234+
datetime(2014, 7, 4, 23): (datetime(2014, 7, 7, 11, 15),
1235+
datetime(2014, 7, 4, 15)),
1236+
datetime(2014, 7, 6, 10): (datetime(2014, 7, 7, 11, 15),
1237+
datetime(2014, 7, 4, 15)),
1238+
datetime(2014, 7, 7, 5): (datetime(2014, 7, 7, 11, 15),
1239+
datetime(2014, 7, 4, 15)),
1240+
datetime(2014, 7, 7, 9, 1): (datetime(2014, 7, 7, 11, 15),
1241+
datetime(2014, 7, 4, 15)),
1242+
datetime(2014, 7, 7, 12): (datetime(2014, 7, 7, 15),
1243+
datetime(2014, 7, 7, 11, 15))}))
1244+
1245+
opening_time_cases.append(([BusinessHour(n=-1, start=['17:00', '08:00'],
1246+
end=['05:00', '10:00']),
1247+
BusinessHour(n=-2, start=['08:00', '17:00'],
1248+
end=['10:00', '03:00'])], {
1249+
datetime(2014, 7, 1, 11): (datetime(2014, 7, 1, 8),
1250+
datetime(2014, 7, 1, 17)),
1251+
datetime(2014, 7, 1, 18): (datetime(2014, 7, 1, 17),
1252+
datetime(2014, 7, 2, 8)),
1253+
datetime(2014, 7, 1, 23): (datetime(2014, 7, 1, 17),
1254+
datetime(2014, 7, 2, 8)),
1255+
datetime(2014, 7, 2, 8): (datetime(2014, 7, 2, 8),
1256+
datetime(2014, 7, 2, 8)),
1257+
datetime(2014, 7, 2, 9): (datetime(2014, 7, 2, 8),
1258+
datetime(2014, 7, 2, 17)),
1259+
datetime(2014, 7, 2, 16, 59): (datetime(2014, 7, 2, 8),
1260+
datetime(2014, 7, 2, 17)),
1261+
datetime(2014, 7, 5, 10): (datetime(2014, 7, 4, 17),
1262+
datetime(2014, 7, 7, 8)),
1263+
datetime(2014, 7, 4, 10): (datetime(2014, 7, 4, 8),
1264+
datetime(2014, 7, 4, 17)),
1265+
datetime(2014, 7, 4, 23): (datetime(2014, 7, 4, 17),
1266+
datetime(2014, 7, 7, 8)),
1267+
datetime(2014, 7, 6, 10): (datetime(2014, 7, 4, 17),
1268+
datetime(2014, 7, 7, 8)),
1269+
datetime(2014, 7, 7, 5): (datetime(2014, 7, 4, 17),
1270+
datetime(2014, 7, 7, 8)),
1271+
datetime(2014, 7, 7, 18): (datetime(2014, 7, 7, 17),
1272+
datetime(2014, 7, 8, 8))}))
1273+
11291274
@pytest.mark.parametrize('case', opening_time_cases)
11301275
def test_opening_time(self, case):
11311276
_offsets, cases = case
@@ -1304,6 +1449,81 @@ def test_opening_time(self, case):
13041449
datetime(2014, 7, 7, 3, 30, 30): datetime(2014, 7, 4, 22, 30, 30),
13051450
datetime(2014, 7, 7, 3, 30, 20): datetime(2014, 7, 4, 22, 30, 20)}))
13061451

1452+
# multiple business hours
1453+
apply_cases.append((BusinessHour(start=['09:00', '14:00'],
1454+
end=['12:00', '18:00']), {
1455+
datetime(2014, 7, 1, 11): datetime(2014, 7, 1, 14),
1456+
datetime(2014, 7, 1, 15): datetime(2014, 7, 1, 16),
1457+
datetime(2014, 7, 1, 19): datetime(2014, 7, 2, 10),
1458+
datetime(2014, 7, 1, 16): datetime(2014, 7, 1, 17),
1459+
datetime(2014, 7, 1, 16, 30, 15): datetime(2014, 7, 1, 17, 30, 15),
1460+
datetime(2014, 7, 1, 17): datetime(2014, 7, 2, 9),
1461+
datetime(2014, 7, 2, 11): datetime(2014, 7, 2, 14),
1462+
# out of business hours
1463+
datetime(2014, 7, 1, 13): datetime(2014, 7, 1, 15),
1464+
datetime(2014, 7, 2, 8): datetime(2014, 7, 2, 10),
1465+
datetime(2014, 7, 2, 19): datetime(2014, 7, 3, 10),
1466+
datetime(2014, 7, 2, 23): datetime(2014, 7, 3, 10),
1467+
datetime(2014, 7, 3, 0): datetime(2014, 7, 3, 10),
1468+
# saturday
1469+
datetime(2014, 7, 5, 15): datetime(2014, 7, 7, 10),
1470+
datetime(2014, 7, 4, 17): datetime(2014, 7, 7, 9),
1471+
datetime(2014, 7, 4, 17, 30): datetime(2014, 7, 7, 9, 30),
1472+
datetime(2014, 7, 4, 17, 30, 30): datetime(2014, 7, 7, 9, 30, 30)}))
1473+
1474+
apply_cases.append((BusinessHour(n=4, start=['09:00', '14:00'],
1475+
end=['12:00', '18:00']), {
1476+
datetime(2014, 7, 1, 11): datetime(2014, 7, 1, 17),
1477+
datetime(2014, 7, 1, 13): datetime(2014, 7, 2, 9),
1478+
datetime(2014, 7, 1, 15): datetime(2014, 7, 2, 10),
1479+
datetime(2014, 7, 1, 16): datetime(2014, 7, 2, 11),
1480+
datetime(2014, 7, 1, 17): datetime(2014, 7, 2, 14),
1481+
datetime(2014, 7, 2, 11): datetime(2014, 7, 2, 17),
1482+
datetime(2014, 7, 2, 8): datetime(2014, 7, 2, 15),
1483+
datetime(2014, 7, 2, 19): datetime(2014, 7, 3, 15),
1484+
datetime(2014, 7, 2, 23): datetime(2014, 7, 3, 15),
1485+
datetime(2014, 7, 3, 0): datetime(2014, 7, 3, 15),
1486+
datetime(2014, 7, 5, 15): datetime(2014, 7, 7, 15),
1487+
datetime(2014, 7, 4, 17): datetime(2014, 7, 7, 14),
1488+
datetime(2014, 7, 4, 16, 30): datetime(2014, 7, 7, 11, 30),
1489+
datetime(2014, 7, 4, 16, 30, 30): datetime(2014, 7, 7, 11, 30, 30)}))
1490+
1491+
apply_cases.append((BusinessHour(n=-4, start=['09:00', '14:00'],
1492+
end=['12:00', '18:00']), {
1493+
datetime(2014, 7, 1, 11): datetime(2014, 6, 30, 16),
1494+
datetime(2014, 7, 1, 13): datetime(2014, 6, 30, 17),
1495+
datetime(2014, 7, 1, 15): datetime(2014, 6, 30, 18),
1496+
datetime(2014, 7, 1, 16): datetime(2014, 7, 1, 10),
1497+
datetime(2014, 7, 1, 17): datetime(2014, 7, 1, 11),
1498+
datetime(2014, 7, 2, 11): datetime(2014, 7, 1, 16),
1499+
datetime(2014, 7, 2, 8): datetime(2014, 7, 1, 12),
1500+
datetime(2014, 7, 2, 19): datetime(2014, 7, 2, 12),
1501+
datetime(2014, 7, 2, 23): datetime(2014, 7, 2, 12),
1502+
datetime(2014, 7, 3, 0): datetime(2014, 7, 2, 12),
1503+
datetime(2014, 7, 5, 15): datetime(2014, 7, 4, 12),
1504+
datetime(2014, 7, 4, 18): datetime(2014, 7, 4, 12),
1505+
datetime(2014, 7, 7, 9, 30): datetime(2014, 7, 4, 14, 30),
1506+
datetime(2014, 7, 7, 9, 30, 30): datetime(2014, 7, 4, 14, 30, 30)}))
1507+
1508+
apply_cases.append((BusinessHour(n=-1, start=['19:00', '03:00'],
1509+
end=['01:00', '05:00']), {
1510+
datetime(2014, 7, 1, 17): datetime(2014, 7, 1, 4),
1511+
datetime(2014, 7, 2, 14): datetime(2014, 7, 2, 4),
1512+
datetime(2014, 7, 2, 8): datetime(2014, 7, 2, 4),
1513+
datetime(2014, 7, 2, 13): datetime(2014, 7, 2, 4),
1514+
datetime(2014, 7, 2, 20): datetime(2014, 7, 2, 5),
1515+
datetime(2014, 7, 2, 19): datetime(2014, 7, 2, 4),
1516+
datetime(2014, 7, 2, 4): datetime(2014, 7, 2, 1),
1517+
datetime(2014, 7, 2, 19, 30): datetime(2014, 7, 2, 4, 30),
1518+
datetime(2014, 7, 3, 0): datetime(2014, 7, 2, 23),
1519+
datetime(2014, 7, 3, 6): datetime(2014, 7, 3, 4),
1520+
datetime(2014, 7, 4, 23): datetime(2014, 7, 4, 22),
1521+
datetime(2014, 7, 5, 0): datetime(2014, 7, 4, 23),
1522+
datetime(2014, 7, 5, 4): datetime(2014, 7, 5, 0),
1523+
datetime(2014, 7, 7, 3, 30): datetime(2014, 7, 5, 0, 30),
1524+
datetime(2014, 7, 7, 19, 30): datetime(2014, 7, 7, 4, 30),
1525+
datetime(2014, 7, 7, 19, 30, 30): datetime(2014, 7, 7, 4, 30, 30)}))
1526+
13071527
@pytest.mark.parametrize('case', apply_cases)
13081528
def test_apply(self, case):
13091529
offset, cases = case
@@ -1360,6 +1580,42 @@ def test_apply(self, case):
13601580
datetime(2014, 7, 7, 1): datetime(2014, 7, 15, 0),
13611581
datetime(2014, 7, 7, 23, 30): datetime(2014, 7, 15, 21, 30)}))
13621582

1583+
# large n for multiple opening hours (3 days and 1 hour before)
1584+
apply_large_n_cases.append((BusinessHour(n=-25, start=['09:00', '14:00'],
1585+
end=['12:00', '19:00']), {
1586+
datetime(2014, 7, 1, 11): datetime(2014, 6, 26, 10),
1587+
datetime(2014, 7, 1, 13): datetime(2014, 6, 26, 11),
1588+
datetime(2014, 7, 1, 9): datetime(2014, 6, 25, 18),
1589+
datetime(2014, 7, 1, 10): datetime(2014, 6, 25, 19),
1590+
datetime(2014, 7, 3, 11): datetime(2014, 6, 30, 10),
1591+
datetime(2014, 7, 3, 8): datetime(2014, 6, 27, 18),
1592+
datetime(2014, 7, 3, 19): datetime(2014, 6, 30, 18),
1593+
datetime(2014, 7, 3, 23): datetime(2014, 6, 30, 18),
1594+
datetime(2014, 7, 4, 9): datetime(2014, 6, 30, 18),
1595+
datetime(2014, 7, 5, 15): datetime(2014, 7, 1, 18),
1596+
datetime(2014, 7, 6, 18): datetime(2014, 7, 1, 18),
1597+
datetime(2014, 7, 7, 9, 30): datetime(2014, 7, 1, 18, 30),
1598+
datetime(2014, 7, 7, 10, 30, 30): datetime(2014, 7, 2, 9, 30, 30)}))
1599+
1600+
# 5 days and 3 hours later
1601+
apply_large_n_cases.append((BusinessHour(28, start=['21:00', '03:00'],
1602+
end=['01:00', '04:00']), {
1603+
datetime(2014, 7, 1, 11): datetime(2014, 7, 9, 0),
1604+
datetime(2014, 7, 1, 22): datetime(2014, 7, 9, 3),
1605+
datetime(2014, 7, 1, 23): datetime(2014, 7, 9, 21),
1606+
datetime(2014, 7, 2, 2): datetime(2014, 7, 9, 23),
1607+
datetime(2014, 7, 3, 21): datetime(2014, 7, 11, 0),
1608+
datetime(2014, 7, 4, 1): datetime(2014, 7, 11, 23),
1609+
datetime(2014, 7, 4, 2): datetime(2014, 7, 11, 23),
1610+
datetime(2014, 7, 4, 3): datetime(2014, 7, 11, 23),
1611+
datetime(2014, 7, 4, 21): datetime(2014, 7, 12, 0),
1612+
datetime(2014, 7, 5, 0): datetime(2014, 7, 14, 22),
1613+
datetime(2014, 7, 5, 1): datetime(2014, 7, 14, 23),
1614+
datetime(2014, 7, 5, 15): datetime(2014, 7, 14, 23),
1615+
datetime(2014, 7, 6, 18): datetime(2014, 7, 14, 23),
1616+
datetime(2014, 7, 7, 1): datetime(2014, 7, 14, 23),
1617+
datetime(2014, 7, 7, 23, 30): datetime(2014, 7, 15, 21, 30)}))
1618+
13631619
@pytest.mark.parametrize('case', apply_large_n_cases)
13641620
def test_apply_large_n(self, case):
13651621
offset, cases = case

0 commit comments

Comments
 (0)