test_datetime.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. import datetime as dt
  2. from datetime import date
  3. import re
  4. import numpy as np
  5. import pytest
  6. from pandas.compat.numpy import np_long
  7. import pandas as pd
  8. from pandas import (
  9. DataFrame,
  10. DatetimeIndex,
  11. Index,
  12. Timestamp,
  13. date_range,
  14. offsets,
  15. )
  16. import pandas._testing as tm
  17. class TestDatetimeIndex:
  18. def test_is_(self):
  19. dti = date_range(start="1/1/2005", end="12/1/2005", freq="ME")
  20. assert dti.is_(dti)
  21. assert dti.is_(dti.view())
  22. assert not dti.is_(dti.copy())
  23. def test_time_overflow_for_32bit_machines(self):
  24. # GH8943. On some machines NumPy defaults to np.int32 (for example,
  25. # 32-bit Linux machines). In the function _generate_regular_range
  26. # found in tseries/index.py, `periods` gets multiplied by `strides`
  27. # (which has value 1e9) and since the max value for np.int32 is ~2e9,
  28. # and since those machines won't promote np.int32 to np.int64, we get
  29. # overflow.
  30. periods = np_long(1000)
  31. idx1 = date_range(start="2000", periods=periods, freq="s")
  32. assert len(idx1) == periods
  33. idx2 = date_range(end="2000", periods=periods, freq="s")
  34. assert len(idx2) == periods
  35. def test_nat(self):
  36. assert DatetimeIndex([np.nan])[0] is pd.NaT
  37. def test_week_of_month_frequency(self):
  38. # GH 5348: "ValueError: Could not evaluate WOM-1SUN" shouldn't raise
  39. d1 = date(2002, 9, 1)
  40. d2 = date(2013, 10, 27)
  41. d3 = date(2012, 9, 30)
  42. idx1 = DatetimeIndex([d1, d2])
  43. idx2 = DatetimeIndex([d3])
  44. result_append = idx1.append(idx2)
  45. expected = DatetimeIndex([d1, d2, d3])
  46. tm.assert_index_equal(result_append, expected)
  47. result_union = idx1.union(idx2)
  48. expected = DatetimeIndex([d1, d3, d2])
  49. tm.assert_index_equal(result_union, expected)
  50. def test_append_nondatetimeindex(self):
  51. rng = date_range("1/1/2000", periods=10)
  52. idx = Index(["a", "b", "c", "d"])
  53. result = rng.append(idx)
  54. assert isinstance(result[0], Timestamp)
  55. def test_misc_coverage(self):
  56. rng = date_range("1/1/2000", periods=5)
  57. result = rng.groupby(rng.day)
  58. assert isinstance(next(iter(result.values()))[0], Timestamp)
  59. # TODO: belongs in frame groupby tests?
  60. def test_groupby_function_tuple_1677(self):
  61. df = DataFrame(
  62. np.random.default_rng(2).random(100),
  63. index=date_range("1/1/2000", periods=100),
  64. )
  65. monthly_group = df.groupby(lambda x: (x.year, x.month))
  66. result = monthly_group.mean()
  67. assert isinstance(result.index[0], tuple)
  68. def assert_index_parameters(self, index):
  69. assert index.freq == "40960ns"
  70. assert index.inferred_freq == "40960ns"
  71. def test_ns_index(self):
  72. nsamples = 400
  73. ns = int(1e9 / 24414)
  74. dtstart = np.datetime64("2012-09-20T00:00:00")
  75. dt = dtstart + np.arange(nsamples) * np.timedelta64(ns, "ns")
  76. freq = ns * offsets.Nano()
  77. index = DatetimeIndex(dt, freq=freq, name="time")
  78. self.assert_index_parameters(index)
  79. new_index = date_range(start=index[0], end=index[-1], freq=index.freq)
  80. self.assert_index_parameters(new_index)
  81. def test_asarray_tz_naive(self):
  82. # This shouldn't produce a warning.
  83. idx = date_range("2000", periods=2)
  84. # M8[ns] by default
  85. result = np.asarray(idx)
  86. expected = np.array(["2000-01-01", "2000-01-02"], dtype="M8[ns]")
  87. tm.assert_numpy_array_equal(result, expected)
  88. # optionally, object
  89. result = np.asarray(idx, dtype=object)
  90. expected = np.array([Timestamp("2000-01-01"), Timestamp("2000-01-02")])
  91. tm.assert_numpy_array_equal(result, expected)
  92. def test_asarray_tz_aware(self):
  93. tz = "US/Central"
  94. idx = date_range("2000", periods=2, tz=tz)
  95. expected = np.array(["2000-01-01T06", "2000-01-02T06"], dtype="M8[ns]")
  96. result = np.asarray(idx, dtype="datetime64[ns]")
  97. tm.assert_numpy_array_equal(result, expected)
  98. # Old behavior with no warning
  99. result = np.asarray(idx, dtype="M8[ns]")
  100. tm.assert_numpy_array_equal(result, expected)
  101. # Future behavior with no warning
  102. expected = np.array(
  103. [Timestamp("2000-01-01", tz=tz), Timestamp("2000-01-02", tz=tz)]
  104. )
  105. result = np.asarray(idx, dtype=object)
  106. tm.assert_numpy_array_equal(result, expected)
  107. def test_CBH_deprecated(self):
  108. msg = "'CBH' is deprecated and will be removed in a future version."
  109. with tm.assert_produces_warning(FutureWarning, match=msg):
  110. expected = date_range(
  111. dt.datetime(2022, 12, 11), dt.datetime(2022, 12, 13), freq="CBH"
  112. )
  113. result = DatetimeIndex(
  114. [
  115. "2022-12-12 09:00:00",
  116. "2022-12-12 10:00:00",
  117. "2022-12-12 11:00:00",
  118. "2022-12-12 12:00:00",
  119. "2022-12-12 13:00:00",
  120. "2022-12-12 14:00:00",
  121. "2022-12-12 15:00:00",
  122. "2022-12-12 16:00:00",
  123. ],
  124. dtype="datetime64[ns]",
  125. freq="cbh",
  126. )
  127. tm.assert_index_equal(result, expected)
  128. @pytest.mark.parametrize(
  129. "freq_depr, expected_values, expected_freq",
  130. [
  131. (
  132. "AS-AUG",
  133. ["2021-08-01", "2022-08-01", "2023-08-01"],
  134. "YS-AUG",
  135. ),
  136. (
  137. "1BAS-MAY",
  138. ["2021-05-03", "2022-05-02", "2023-05-01"],
  139. "1BYS-MAY",
  140. ),
  141. ],
  142. )
  143. def test_AS_BAS_deprecated(self, freq_depr, expected_values, expected_freq):
  144. # GH#55479
  145. freq_msg = re.split("[0-9]*", freq_depr, maxsplit=1)[1]
  146. msg = f"'{freq_msg}' is deprecated and will be removed in a future version."
  147. with tm.assert_produces_warning(FutureWarning, match=msg):
  148. expected = date_range(
  149. dt.datetime(2020, 12, 1), dt.datetime(2023, 12, 1), freq=freq_depr
  150. )
  151. result = DatetimeIndex(
  152. expected_values,
  153. dtype="datetime64[ns]",
  154. freq=expected_freq,
  155. )
  156. tm.assert_index_equal(result, expected)
  157. @pytest.mark.parametrize(
  158. "freq, expected_values, freq_depr",
  159. [
  160. ("2BYE-MAR", ["2016-03-31"], "2BA-MAR"),
  161. ("2BYE-JUN", ["2016-06-30"], "2BY-JUN"),
  162. ("2BME", ["2016-02-29", "2016-04-29", "2016-06-30"], "2BM"),
  163. ("2BQE", ["2016-03-31"], "2BQ"),
  164. ("1BQE-MAR", ["2016-03-31", "2016-06-30"], "1BQ-MAR"),
  165. ],
  166. )
  167. def test_BM_BQ_BY_deprecated(self, freq, expected_values, freq_depr):
  168. # GH#52064
  169. msg = f"'{freq_depr[1:]}' is deprecated and will be removed "
  170. f"in a future version, please use '{freq[1:]}' instead."
  171. with tm.assert_produces_warning(FutureWarning, match=msg):
  172. expected = date_range(start="2016-02-21", end="2016-08-21", freq=freq_depr)
  173. result = DatetimeIndex(
  174. data=expected_values,
  175. dtype="datetime64[ns]",
  176. freq=freq,
  177. )
  178. tm.assert_index_equal(result, expected)