test_to_period.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. import warnings
  2. import dateutil.tz
  3. from dateutil.tz import tzlocal
  4. import pytest
  5. import pytz
  6. from pandas._libs.tslibs.ccalendar import MONTHS
  7. from pandas._libs.tslibs.period import INVALID_FREQ_ERR_MSG
  8. from pandas import (
  9. DatetimeIndex,
  10. Period,
  11. PeriodIndex,
  12. Timestamp,
  13. date_range,
  14. period_range,
  15. )
  16. import pandas._testing as tm
  17. class TestToPeriod:
  18. def test_dti_to_period(self):
  19. dti = date_range(start="1/1/2005", end="12/1/2005", freq="M")
  20. pi1 = dti.to_period()
  21. pi2 = dti.to_period(freq="D")
  22. pi3 = dti.to_period(freq="3D")
  23. assert pi1[0] == Period("Jan 2005", freq="M")
  24. assert pi2[0] == Period("1/31/2005", freq="D")
  25. assert pi3[0] == Period("1/31/2005", freq="3D")
  26. assert pi1[-1] == Period("Nov 2005", freq="M")
  27. assert pi2[-1] == Period("11/30/2005", freq="D")
  28. assert pi3[-1], Period("11/30/2005", freq="3D")
  29. tm.assert_index_equal(pi1, period_range("1/1/2005", "11/1/2005", freq="M"))
  30. tm.assert_index_equal(
  31. pi2, period_range("1/1/2005", "11/1/2005", freq="M").asfreq("D")
  32. )
  33. tm.assert_index_equal(
  34. pi3, period_range("1/1/2005", "11/1/2005", freq="M").asfreq("3D")
  35. )
  36. @pytest.mark.parametrize("month", MONTHS)
  37. def test_to_period_quarterly(self, month):
  38. # make sure we can make the round trip
  39. freq = f"Q-{month}"
  40. rng = period_range("1989Q3", "1991Q3", freq=freq)
  41. stamps = rng.to_timestamp()
  42. result = stamps.to_period(freq)
  43. tm.assert_index_equal(rng, result)
  44. @pytest.mark.parametrize("off", ["BQ", "QS", "BQS"])
  45. def test_to_period_quarterlyish(self, off):
  46. rng = date_range("01-Jan-2012", periods=8, freq=off)
  47. prng = rng.to_period()
  48. assert prng.freq == "Q-DEC"
  49. @pytest.mark.parametrize("off", ["BA", "AS", "BAS"])
  50. def test_to_period_annualish(self, off):
  51. rng = date_range("01-Jan-2012", periods=8, freq=off)
  52. prng = rng.to_period()
  53. assert prng.freq == "A-DEC"
  54. def test_to_period_monthish(self):
  55. offsets = ["MS", "BM"]
  56. for off in offsets:
  57. rng = date_range("01-Jan-2012", periods=8, freq=off)
  58. prng = rng.to_period()
  59. assert prng.freq == "M"
  60. rng = date_range("01-Jan-2012", periods=8, freq="M")
  61. prng = rng.to_period()
  62. assert prng.freq == "M"
  63. with pytest.raises(ValueError, match=INVALID_FREQ_ERR_MSG):
  64. date_range("01-Jan-2012", periods=8, freq="EOM")
  65. def test_to_period_infer(self):
  66. # https://github.com/pandas-dev/pandas/issues/33358
  67. rng = date_range(
  68. start="2019-12-22 06:40:00+00:00",
  69. end="2019-12-22 08:45:00+00:00",
  70. freq="5min",
  71. )
  72. with tm.assert_produces_warning(None):
  73. # Using simple filter because we are not checking for the warning here
  74. warnings.simplefilter("ignore", UserWarning)
  75. pi1 = rng.to_period("5min")
  76. with tm.assert_produces_warning(None):
  77. # Using simple filter because we are not checking for the warning here
  78. warnings.simplefilter("ignore", UserWarning)
  79. pi2 = rng.to_period()
  80. tm.assert_index_equal(pi1, pi2)
  81. def test_period_dt64_round_trip(self):
  82. dti = date_range("1/1/2000", "1/7/2002", freq="B")
  83. pi = dti.to_period()
  84. tm.assert_index_equal(pi.to_timestamp(), dti)
  85. dti = date_range("1/1/2000", "1/7/2002", freq="B")
  86. pi = dti.to_period(freq="H")
  87. tm.assert_index_equal(pi.to_timestamp(), dti)
  88. def test_to_period_millisecond(self):
  89. index = DatetimeIndex(
  90. [
  91. Timestamp("2007-01-01 10:11:12.123456Z"),
  92. Timestamp("2007-01-01 10:11:13.789123Z"),
  93. ]
  94. )
  95. with tm.assert_produces_warning(UserWarning):
  96. # warning that timezone info will be lost
  97. period = index.to_period(freq="L")
  98. assert 2 == len(period)
  99. assert period[0] == Period("2007-01-01 10:11:12.123Z", "L")
  100. assert period[1] == Period("2007-01-01 10:11:13.789Z", "L")
  101. def test_to_period_microsecond(self):
  102. index = DatetimeIndex(
  103. [
  104. Timestamp("2007-01-01 10:11:12.123456Z"),
  105. Timestamp("2007-01-01 10:11:13.789123Z"),
  106. ]
  107. )
  108. with tm.assert_produces_warning(UserWarning):
  109. # warning that timezone info will be lost
  110. period = index.to_period(freq="U")
  111. assert 2 == len(period)
  112. assert period[0] == Period("2007-01-01 10:11:12.123456Z", "U")
  113. assert period[1] == Period("2007-01-01 10:11:13.789123Z", "U")
  114. @pytest.mark.parametrize(
  115. "tz",
  116. ["US/Eastern", pytz.utc, tzlocal(), "dateutil/US/Eastern", dateutil.tz.tzutc()],
  117. )
  118. def test_to_period_tz(self, tz):
  119. ts = date_range("1/1/2000", "2/1/2000", tz=tz)
  120. with tm.assert_produces_warning(UserWarning):
  121. # GH#21333 warning that timezone info will be lost
  122. # filter warning about freq deprecation
  123. result = ts.to_period()[0]
  124. expected = ts[0].to_period(ts.freq)
  125. assert result == expected
  126. expected = date_range("1/1/2000", "2/1/2000").to_period()
  127. with tm.assert_produces_warning(UserWarning):
  128. # GH#21333 warning that timezone info will be lost
  129. result = ts.to_period(ts.freq)
  130. tm.assert_index_equal(result, expected)
  131. @pytest.mark.parametrize("tz", ["Etc/GMT-1", "Etc/GMT+1"])
  132. def test_to_period_tz_utc_offset_consistency(self, tz):
  133. # GH#22905
  134. ts = date_range("1/1/2000", "2/1/2000", tz="Etc/GMT-1")
  135. with tm.assert_produces_warning(UserWarning):
  136. result = ts.to_period()[0]
  137. expected = ts[0].to_period(ts.freq)
  138. assert result == expected
  139. def test_to_period_nofreq(self):
  140. idx = DatetimeIndex(["2000-01-01", "2000-01-02", "2000-01-04"])
  141. msg = "You must pass a freq argument as current index has none."
  142. with pytest.raises(ValueError, match=msg):
  143. idx.to_period()
  144. idx = DatetimeIndex(["2000-01-01", "2000-01-02", "2000-01-03"], freq="infer")
  145. assert idx.freqstr == "D"
  146. expected = PeriodIndex(["2000-01-01", "2000-01-02", "2000-01-03"], freq="D")
  147. tm.assert_index_equal(idx.to_period(), expected)
  148. # GH#7606
  149. idx = DatetimeIndex(["2000-01-01", "2000-01-02", "2000-01-03"])
  150. assert idx.freqstr is None
  151. tm.assert_index_equal(idx.to_period(), expected)