test_liboffsets.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. # -*- coding: utf-8 -*-
  2. """
  3. Tests for helper functions in the cython tslibs.offsets
  4. """
  5. from datetime import datetime
  6. import pytest
  7. import pandas._libs.tslibs.offsets as liboffsets
  8. from pandas._libs.tslibs.offsets import roll_qtrday
  9. from pandas import Timestamp
  10. @pytest.fixture(params=["start", "end", "business_start", "business_end"])
  11. def day_opt(request):
  12. return request.param
  13. @pytest.mark.parametrize("dt,exp_week_day,exp_last_day", [
  14. (datetime(2017, 11, 30), 3, 30), # Business day.
  15. (datetime(1993, 10, 31), 6, 29) # Non-business day.
  16. ])
  17. def test_get_last_bday(dt, exp_week_day, exp_last_day):
  18. assert dt.weekday() == exp_week_day
  19. assert liboffsets.get_lastbday(dt.year, dt.month) == exp_last_day
  20. @pytest.mark.parametrize("dt,exp_week_day,exp_first_day", [
  21. (datetime(2017, 4, 1), 5, 3), # Non-weekday.
  22. (datetime(1993, 10, 1), 4, 1) # Business day.
  23. ])
  24. def test_get_first_bday(dt, exp_week_day, exp_first_day):
  25. assert dt.weekday() == exp_week_day
  26. assert liboffsets.get_firstbday(dt.year, dt.month) == exp_first_day
  27. @pytest.mark.parametrize("months,day_opt,expected", [
  28. (0, 15, datetime(2017, 11, 15)),
  29. (0, None, datetime(2017, 11, 30)),
  30. (1, "start", datetime(2017, 12, 1)),
  31. (-145, "end", datetime(2005, 10, 31)),
  32. (0, "business_end", datetime(2017, 11, 30)),
  33. (0, "business_start", datetime(2017, 11, 1))
  34. ])
  35. def test_shift_month_dt(months, day_opt, expected):
  36. dt = datetime(2017, 11, 30)
  37. assert liboffsets.shift_month(dt, months, day_opt=day_opt) == expected
  38. @pytest.mark.parametrize("months,day_opt,expected", [
  39. (1, "start", Timestamp("1929-06-01")),
  40. (-3, "end", Timestamp("1929-02-28")),
  41. (25, None, Timestamp("1931-06-5")),
  42. (-1, 31, Timestamp("1929-04-30"))
  43. ])
  44. def test_shift_month_ts(months, day_opt, expected):
  45. ts = Timestamp("1929-05-05")
  46. assert liboffsets.shift_month(ts, months, day_opt=day_opt) == expected
  47. def test_shift_month_error():
  48. dt = datetime(2017, 11, 15)
  49. day_opt = "this should raise"
  50. with pytest.raises(ValueError, match=day_opt):
  51. liboffsets.shift_month(dt, 3, day_opt=day_opt)
  52. @pytest.mark.parametrize("other,expected", [
  53. # Before March 1.
  54. (datetime(2017, 2, 10), {2: 1, -7: -7, 0: 0}),
  55. # After March 1.
  56. (Timestamp("2014-03-15", tz="US/Eastern"), {2: 2, -7: -6, 0: 1})
  57. ])
  58. @pytest.mark.parametrize("n", [2, -7, 0])
  59. def test_roll_yearday(other, expected, n):
  60. month = 3
  61. day_opt = "start" # `other` will be compared to March 1.
  62. assert liboffsets.roll_yearday(other, n, month, day_opt) == expected[n]
  63. @pytest.mark.parametrize("other,expected", [
  64. # Before June 30.
  65. (datetime(1999, 6, 29), {5: 4, -7: -7, 0: 0}),
  66. # After June 30.
  67. (Timestamp(2072, 8, 24, 6, 17, 18), {5: 5, -7: -6, 0: 1})
  68. ])
  69. @pytest.mark.parametrize("n", [5, -7, 0])
  70. def test_roll_yearday2(other, expected, n):
  71. month = 6
  72. day_opt = "end" # `other` will be compared to June 30.
  73. assert liboffsets.roll_yearday(other, n, month, day_opt) == expected[n]
  74. def test_get_day_of_month_error():
  75. # get_day_of_month is not directly exposed.
  76. # We test it via roll_yearday.
  77. dt = datetime(2017, 11, 15)
  78. day_opt = "foo"
  79. with pytest.raises(ValueError, match=day_opt):
  80. # To hit the raising case we need month == dt.month and n > 0.
  81. liboffsets.roll_yearday(dt, n=3, month=11, day_opt=day_opt)
  82. @pytest.mark.parametrize("month", [
  83. 3, # (other.month % 3) < (month % 3)
  84. 5 # (other.month % 3) > (month % 3)
  85. ])
  86. @pytest.mark.parametrize("n", [4, -3])
  87. def test_roll_qtr_day_not_mod_unequal(day_opt, month, n):
  88. expected = {
  89. 3: {
  90. -3: -2,
  91. 4: 4
  92. },
  93. 5: {
  94. -3: -3,
  95. 4: 3
  96. }
  97. }
  98. other = Timestamp(2072, 10, 1, 6, 17, 18) # Saturday.
  99. assert roll_qtrday(other, n, month, day_opt, modby=3) == expected[month][n]
  100. @pytest.mark.parametrize("other,month,exp_dict", [
  101. # Monday.
  102. (datetime(1999, 5, 31), 2, {
  103. -1: {
  104. "start": 0,
  105. "business_start": 0
  106. }
  107. }),
  108. # Saturday.
  109. (Timestamp(2072, 10, 1, 6, 17, 18), 4, {
  110. 2: {
  111. "end": 1,
  112. "business_end": 1,
  113. "business_start": 1
  114. }
  115. }),
  116. # First business day.
  117. (Timestamp(2072, 10, 3, 6, 17, 18), 4, {
  118. 2: {
  119. "end": 1,
  120. "business_end": 1
  121. },
  122. -1: {
  123. "start": 0
  124. }
  125. })
  126. ])
  127. @pytest.mark.parametrize("n", [2, -1])
  128. def test_roll_qtr_day_mod_equal(other, month, exp_dict, n, day_opt):
  129. # All cases have (other.month % 3) == (month % 3).
  130. expected = exp_dict.get(n, {}).get(day_opt, n)
  131. assert roll_qtrday(other, n, month, day_opt, modby=3) == expected
  132. @pytest.mark.parametrize("n,expected", [
  133. (42, {29: 42, 1: 42, 31: 41}),
  134. (-4, {29: -4, 1: -3, 31: -4})
  135. ])
  136. @pytest.mark.parametrize("compare", [29, 1, 31])
  137. def test_roll_convention(n, expected, compare):
  138. assert liboffsets.roll_convention(29, n, compare) == expected[compare]