test_timedeltas.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import re
  2. import numpy as np
  3. import pytest
  4. from pandas._libs.tslibs.timedeltas import (
  5. array_to_timedelta64,
  6. delta_to_nanoseconds,
  7. ints_to_pytimedelta,
  8. )
  9. from pandas import (
  10. Timedelta,
  11. offsets,
  12. )
  13. import pandas._testing as tm
  14. @pytest.mark.parametrize(
  15. "obj,expected",
  16. [
  17. (np.timedelta64(14, "D"), 14 * 24 * 3600 * 1e9),
  18. (Timedelta(minutes=-7), -7 * 60 * 1e9),
  19. (Timedelta(minutes=-7).to_pytimedelta(), -7 * 60 * 1e9),
  20. (Timedelta(seconds=1234e-9), 1234), # GH43764, GH40946
  21. (
  22. Timedelta(seconds=1e-9, milliseconds=1e-5, microseconds=1e-1),
  23. 111,
  24. ), # GH43764
  25. (
  26. Timedelta(days=1, seconds=1e-9, milliseconds=1e-5, microseconds=1e-1),
  27. 24 * 3600e9 + 111,
  28. ), # GH43764
  29. (offsets.Nano(125), 125),
  30. ],
  31. )
  32. def test_delta_to_nanoseconds(obj, expected):
  33. result = delta_to_nanoseconds(obj)
  34. assert result == expected
  35. def test_delta_to_nanoseconds_error():
  36. obj = np.array([123456789], dtype="m8[ns]")
  37. with pytest.raises(TypeError, match="<class 'numpy.ndarray'>"):
  38. delta_to_nanoseconds(obj)
  39. with pytest.raises(TypeError, match="float"):
  40. delta_to_nanoseconds(1.5)
  41. with pytest.raises(TypeError, match="int"):
  42. delta_to_nanoseconds(1)
  43. with pytest.raises(TypeError, match="int"):
  44. delta_to_nanoseconds(np.int64(2))
  45. with pytest.raises(TypeError, match="int"):
  46. delta_to_nanoseconds(np.int32(3))
  47. def test_delta_to_nanoseconds_td64_MY_raises():
  48. msg = (
  49. "delta_to_nanoseconds does not support Y or M units, "
  50. "as their duration in nanoseconds is ambiguous"
  51. )
  52. td = np.timedelta64(1234, "Y")
  53. with pytest.raises(ValueError, match=msg):
  54. delta_to_nanoseconds(td)
  55. td = np.timedelta64(1234, "M")
  56. with pytest.raises(ValueError, match=msg):
  57. delta_to_nanoseconds(td)
  58. def test_huge_nanoseconds_overflow():
  59. # GH 32402
  60. assert delta_to_nanoseconds(Timedelta(1e10)) == 1e10
  61. assert delta_to_nanoseconds(Timedelta(nanoseconds=1e10)) == 1e10
  62. @pytest.mark.parametrize(
  63. "kwargs", [{"Seconds": 1}, {"seconds": 1, "Nanoseconds": 1}, {"Foo": 2}]
  64. )
  65. def test_kwarg_assertion(kwargs):
  66. err_message = (
  67. "cannot construct a Timedelta from the passed arguments, "
  68. "allowed keywords are "
  69. "[weeks, days, hours, minutes, seconds, "
  70. "milliseconds, microseconds, nanoseconds]"
  71. )
  72. with pytest.raises(ValueError, match=re.escape(err_message)):
  73. Timedelta(**kwargs)
  74. class TestArrayToTimedelta64:
  75. def test_array_to_timedelta64_string_with_unit_2d_raises(self):
  76. # check the 'unit is not None and errors != "coerce"' path
  77. # in array_to_timedelta64 raises correctly with 2D values
  78. values = np.array([["1", 2], [3, "4"]], dtype=object)
  79. with pytest.raises(ValueError, match="unit must not be specified"):
  80. array_to_timedelta64(values, unit="s")
  81. def test_array_to_timedelta64_non_object_raises(self):
  82. # check we raise, not segfault
  83. values = np.arange(5)
  84. msg = "'values' must have object dtype"
  85. with pytest.raises(TypeError, match=msg):
  86. array_to_timedelta64(values)
  87. @pytest.mark.parametrize("unit", ["s", "ms", "us"])
  88. def test_ints_to_pytimedelta(unit):
  89. # tests for non-nanosecond cases
  90. arr = np.arange(6, dtype=np.int64).view(f"m8[{unit}]")
  91. res = ints_to_pytimedelta(arr, box=False)
  92. # For non-nanosecond, .astype(object) gives pytimedelta objects
  93. # instead of integers
  94. expected = arr.astype(object)
  95. tm.assert_numpy_array_equal(res, expected)
  96. res = ints_to_pytimedelta(arr, box=True)
  97. expected = np.array([Timedelta(x) for x in arr], dtype=object)
  98. tm.assert_numpy_array_equal(res, expected)
  99. @pytest.mark.parametrize("unit", ["Y", "M", "ps", "fs", "as"])
  100. def test_ints_to_pytimedelta_unsupported(unit):
  101. arr = np.arange(6, dtype=np.int64).view(f"m8[{unit}]")
  102. with pytest.raises(NotImplementedError, match=r"\d{1,2}"):
  103. ints_to_pytimedelta(arr, box=False)
  104. msg = "Only resolutions 's', 'ms', 'us', 'ns' are supported"
  105. with pytest.raises(NotImplementedError, match=msg):
  106. ints_to_pytimedelta(arr, box=True)