test_business_day.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. """
  2. Tests for offsets.BDay
  3. """
  4. from __future__ import annotations
  5. from datetime import (
  6. date,
  7. datetime,
  8. timedelta,
  9. )
  10. import numpy as np
  11. import pytest
  12. from pandas._libs.tslibs.offsets import (
  13. ApplyTypeError,
  14. BDay,
  15. BMonthEnd,
  16. )
  17. from pandas import (
  18. DatetimeIndex,
  19. Timedelta,
  20. _testing as tm,
  21. )
  22. from pandas.tests.tseries.offsets.common import (
  23. assert_is_on_offset,
  24. assert_offset_equal,
  25. )
  26. from pandas.tseries import offsets
  27. @pytest.fixture
  28. def dt():
  29. return datetime(2008, 1, 1)
  30. @pytest.fixture
  31. def _offset():
  32. return BDay
  33. @pytest.fixture
  34. def offset(_offset):
  35. return _offset()
  36. @pytest.fixture
  37. def offset2(_offset):
  38. return _offset(2)
  39. class TestBusinessDay:
  40. def test_different_normalize_equals(self, _offset, offset2):
  41. # GH#21404 changed __eq__ to return False when `normalize` does not match
  42. offset = _offset()
  43. offset2 = _offset(normalize=True)
  44. assert offset != offset2
  45. def test_repr(self, offset, offset2):
  46. assert repr(offset) == "<BusinessDay>"
  47. assert repr(offset2) == "<2 * BusinessDays>"
  48. expected = "<BusinessDay: offset=datetime.timedelta(days=1)>"
  49. assert repr(offset + timedelta(1)) == expected
  50. def test_with_offset(self, dt, offset):
  51. offset = offset + timedelta(hours=2)
  52. assert (dt + offset) == datetime(2008, 1, 2, 2)
  53. @pytest.mark.parametrize(
  54. "td",
  55. [
  56. Timedelta(hours=2),
  57. Timedelta(hours=2).to_pytimedelta(),
  58. Timedelta(hours=2).to_timedelta64(),
  59. ],
  60. ids=lambda x: type(x),
  61. )
  62. def test_with_offset_index(self, td, dt, offset):
  63. dti = DatetimeIndex([dt])
  64. expected = DatetimeIndex([datetime(2008, 1, 2, 2)])
  65. result = dti + (td + offset)
  66. tm.assert_index_equal(result, expected)
  67. result = dti + (offset + td)
  68. tm.assert_index_equal(result, expected)
  69. def test_eq(self, offset2):
  70. assert offset2 == offset2
  71. def test_hash(self, offset2):
  72. assert hash(offset2) == hash(offset2)
  73. def test_add_datetime(self, dt, offset2):
  74. assert offset2 + dt == datetime(2008, 1, 3)
  75. assert offset2 + np.datetime64("2008-01-01 00:00:00") == datetime(2008, 1, 3)
  76. def testRollback1(self, dt, _offset):
  77. assert _offset(10).rollback(dt) == dt
  78. def testRollback2(self, _offset):
  79. assert _offset(10).rollback(datetime(2008, 1, 5)) == datetime(2008, 1, 4)
  80. def testRollforward1(self, dt, _offset):
  81. assert _offset(10).rollforward(dt) == dt
  82. def testRollforward2(self, _offset):
  83. assert _offset(10).rollforward(datetime(2008, 1, 5)) == datetime(2008, 1, 7)
  84. def test_roll_date_object(self, offset):
  85. dt = date(2012, 9, 15)
  86. result = offset.rollback(dt)
  87. assert result == datetime(2012, 9, 14)
  88. result = offset.rollforward(dt)
  89. assert result == datetime(2012, 9, 17)
  90. offset = offsets.Day()
  91. result = offset.rollback(dt)
  92. assert result == datetime(2012, 9, 15)
  93. result = offset.rollforward(dt)
  94. assert result == datetime(2012, 9, 15)
  95. @pytest.mark.parametrize(
  96. "dt, expected",
  97. [
  98. (datetime(2008, 1, 1), True),
  99. (datetime(2008, 1, 5), False),
  100. ],
  101. )
  102. def test_is_on_offset(self, offset, dt, expected):
  103. assert_is_on_offset(offset, dt, expected)
  104. apply_cases: list[tuple[int, dict[datetime, datetime]]] = [
  105. (
  106. 1,
  107. {
  108. datetime(2008, 1, 1): datetime(2008, 1, 2),
  109. datetime(2008, 1, 4): datetime(2008, 1, 7),
  110. datetime(2008, 1, 5): datetime(2008, 1, 7),
  111. datetime(2008, 1, 6): datetime(2008, 1, 7),
  112. datetime(2008, 1, 7): datetime(2008, 1, 8),
  113. },
  114. ),
  115. (
  116. 2,
  117. {
  118. datetime(2008, 1, 1): datetime(2008, 1, 3),
  119. datetime(2008, 1, 4): datetime(2008, 1, 8),
  120. datetime(2008, 1, 5): datetime(2008, 1, 8),
  121. datetime(2008, 1, 6): datetime(2008, 1, 8),
  122. datetime(2008, 1, 7): datetime(2008, 1, 9),
  123. },
  124. ),
  125. (
  126. -1,
  127. {
  128. datetime(2008, 1, 1): datetime(2007, 12, 31),
  129. datetime(2008, 1, 4): datetime(2008, 1, 3),
  130. datetime(2008, 1, 5): datetime(2008, 1, 4),
  131. datetime(2008, 1, 6): datetime(2008, 1, 4),
  132. datetime(2008, 1, 7): datetime(2008, 1, 4),
  133. datetime(2008, 1, 8): datetime(2008, 1, 7),
  134. },
  135. ),
  136. (
  137. -2,
  138. {
  139. datetime(2008, 1, 1): datetime(2007, 12, 28),
  140. datetime(2008, 1, 4): datetime(2008, 1, 2),
  141. datetime(2008, 1, 5): datetime(2008, 1, 3),
  142. datetime(2008, 1, 6): datetime(2008, 1, 3),
  143. datetime(2008, 1, 7): datetime(2008, 1, 3),
  144. datetime(2008, 1, 8): datetime(2008, 1, 4),
  145. datetime(2008, 1, 9): datetime(2008, 1, 7),
  146. },
  147. ),
  148. (
  149. 0,
  150. {
  151. datetime(2008, 1, 1): datetime(2008, 1, 1),
  152. datetime(2008, 1, 4): datetime(2008, 1, 4),
  153. datetime(2008, 1, 5): datetime(2008, 1, 7),
  154. datetime(2008, 1, 6): datetime(2008, 1, 7),
  155. datetime(2008, 1, 7): datetime(2008, 1, 7),
  156. },
  157. ),
  158. ]
  159. @pytest.mark.parametrize("case", apply_cases)
  160. def test_apply(self, case, _offset):
  161. n, cases = case
  162. offset = _offset(n)
  163. for base, expected in cases.items():
  164. assert_offset_equal(offset, base, expected)
  165. def test_apply_large_n(self, _offset):
  166. dt = datetime(2012, 10, 23)
  167. result = dt + _offset(10)
  168. assert result == datetime(2012, 11, 6)
  169. result = dt + _offset(100) - _offset(100)
  170. assert result == dt
  171. off = _offset() * 6
  172. rs = datetime(2012, 1, 1) - off
  173. xp = datetime(2011, 12, 23)
  174. assert rs == xp
  175. st = datetime(2011, 12, 18)
  176. rs = st + off
  177. xp = datetime(2011, 12, 26)
  178. assert rs == xp
  179. off = _offset() * 10
  180. rs = datetime(2014, 1, 5) + off # see #5890
  181. xp = datetime(2014, 1, 17)
  182. assert rs == xp
  183. def test_apply_corner(self, _offset):
  184. if _offset is BDay:
  185. msg = "Only know how to combine business day with datetime or timedelta"
  186. else:
  187. msg = (
  188. "Only know how to combine trading day "
  189. "with datetime, datetime64 or timedelta"
  190. )
  191. with pytest.raises(ApplyTypeError, match=msg):
  192. _offset()._apply(BMonthEnd())