test_construction.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. # -*- coding: utf-8 -*-
  2. from datetime import timedelta
  3. import numpy as np
  4. import pytest
  5. from pandas import Timedelta, offsets, to_timedelta
  6. def test_construction():
  7. expected = np.timedelta64(10, 'D').astype('m8[ns]').view('i8')
  8. assert Timedelta(10, unit='d').value == expected
  9. assert Timedelta(10.0, unit='d').value == expected
  10. assert Timedelta('10 days').value == expected
  11. assert Timedelta(days=10).value == expected
  12. assert Timedelta(days=10.0).value == expected
  13. expected += np.timedelta64(10, 's').astype('m8[ns]').view('i8')
  14. assert Timedelta('10 days 00:00:10').value == expected
  15. assert Timedelta(days=10, seconds=10).value == expected
  16. assert Timedelta(days=10, milliseconds=10 * 1000).value == expected
  17. assert Timedelta(days=10,
  18. microseconds=10 * 1000 * 1000).value == expected
  19. # rounding cases
  20. assert Timedelta(82739999850000).value == 82739999850000
  21. assert ('0 days 22:58:59.999850' in str(Timedelta(82739999850000)))
  22. assert Timedelta(123072001000000).value == 123072001000000
  23. assert ('1 days 10:11:12.001' in str(Timedelta(123072001000000)))
  24. # string conversion with/without leading zero
  25. # GH#9570
  26. assert Timedelta('0:00:00') == timedelta(hours=0)
  27. assert Timedelta('00:00:00') == timedelta(hours=0)
  28. assert Timedelta('-1:00:00') == -timedelta(hours=1)
  29. assert Timedelta('-01:00:00') == -timedelta(hours=1)
  30. # more strings & abbrevs
  31. # GH#8190
  32. assert Timedelta('1 h') == timedelta(hours=1)
  33. assert Timedelta('1 hour') == timedelta(hours=1)
  34. assert Timedelta('1 hr') == timedelta(hours=1)
  35. assert Timedelta('1 hours') == timedelta(hours=1)
  36. assert Timedelta('-1 hours') == -timedelta(hours=1)
  37. assert Timedelta('1 m') == timedelta(minutes=1)
  38. assert Timedelta('1.5 m') == timedelta(seconds=90)
  39. assert Timedelta('1 minute') == timedelta(minutes=1)
  40. assert Timedelta('1 minutes') == timedelta(minutes=1)
  41. assert Timedelta('1 s') == timedelta(seconds=1)
  42. assert Timedelta('1 second') == timedelta(seconds=1)
  43. assert Timedelta('1 seconds') == timedelta(seconds=1)
  44. assert Timedelta('1 ms') == timedelta(milliseconds=1)
  45. assert Timedelta('1 milli') == timedelta(milliseconds=1)
  46. assert Timedelta('1 millisecond') == timedelta(milliseconds=1)
  47. assert Timedelta('1 us') == timedelta(microseconds=1)
  48. assert Timedelta('1 micros') == timedelta(microseconds=1)
  49. assert Timedelta('1 microsecond') == timedelta(microseconds=1)
  50. assert Timedelta('1.5 microsecond') == Timedelta('00:00:00.000001500')
  51. assert Timedelta('1 ns') == Timedelta('00:00:00.000000001')
  52. assert Timedelta('1 nano') == Timedelta('00:00:00.000000001')
  53. assert Timedelta('1 nanosecond') == Timedelta('00:00:00.000000001')
  54. # combos
  55. assert Timedelta('10 days 1 hour') == timedelta(days=10, hours=1)
  56. assert Timedelta('10 days 1 h') == timedelta(days=10, hours=1)
  57. assert Timedelta('10 days 1 h 1m 1s') == timedelta(
  58. days=10, hours=1, minutes=1, seconds=1)
  59. assert Timedelta('-10 days 1 h 1m 1s') == -timedelta(
  60. days=10, hours=1, minutes=1, seconds=1)
  61. assert Timedelta('-10 days 1 h 1m 1s') == -timedelta(
  62. days=10, hours=1, minutes=1, seconds=1)
  63. assert Timedelta('-10 days 1 h 1m 1s 3us') == -timedelta(
  64. days=10, hours=1, minutes=1, seconds=1, microseconds=3)
  65. assert Timedelta('-10 days 1 h 1.5m 1s 3us') == -timedelta(
  66. days=10, hours=1, minutes=1, seconds=31, microseconds=3)
  67. # Currently invalid as it has a - on the hh:mm:dd part
  68. # (only allowed on the days)
  69. with pytest.raises(ValueError):
  70. Timedelta('-10 days -1 h 1.5m 1s 3us')
  71. # only leading neg signs are allowed
  72. with pytest.raises(ValueError):
  73. Timedelta('10 days -1 h 1.5m 1s 3us')
  74. # no units specified
  75. with pytest.raises(ValueError):
  76. Timedelta('3.1415')
  77. # invalid construction
  78. with pytest.raises(ValueError, match="cannot construct a Timedelta"):
  79. Timedelta()
  80. with pytest.raises(ValueError, match="unit abbreviation w/o a number"):
  81. Timedelta('foo')
  82. msg = ("cannot construct a Timedelta from "
  83. "the passed arguments, allowed keywords are ")
  84. with pytest.raises(ValueError, match=msg):
  85. Timedelta(day=10)
  86. # floats
  87. expected = np.timedelta64(
  88. 10, 's').astype('m8[ns]').view('i8') + np.timedelta64(
  89. 500, 'ms').astype('m8[ns]').view('i8')
  90. assert Timedelta(10.5, unit='s').value == expected
  91. # offset
  92. assert to_timedelta(offsets.Hour(2)) == Timedelta(hours=2)
  93. assert Timedelta(offsets.Hour(2)) == Timedelta(hours=2)
  94. assert Timedelta(offsets.Second(2)) == Timedelta(seconds=2)
  95. # GH#11995: unicode
  96. expected = Timedelta('1H')
  97. result = Timedelta(u'1H')
  98. assert result == expected
  99. assert to_timedelta(offsets.Hour(2)) == Timedelta(u'0 days, 02:00:00')
  100. with pytest.raises(ValueError):
  101. Timedelta(u'foo bar')
  102. @pytest.mark.parametrize('item', list({'days': 'D',
  103. 'seconds': 's',
  104. 'microseconds': 'us',
  105. 'milliseconds': 'ms',
  106. 'minutes': 'm',
  107. 'hours': 'h',
  108. 'weeks': 'W'}.items()))
  109. @pytest.mark.parametrize('npdtype', [np.int64, np.int32, np.int16,
  110. np.float64, np.float32, np.float16])
  111. def test_td_construction_with_np_dtypes(npdtype, item):
  112. # GH#8757: test construction with np dtypes
  113. pykwarg, npkwarg = item
  114. expected = np.timedelta64(1, npkwarg).astype('m8[ns]').view('i8')
  115. assert Timedelta(**{pykwarg: npdtype(1)}).value == expected
  116. @pytest.mark.parametrize('val', [
  117. '1s', '-1s', '1us', '-1us', '1 day', '-1 day',
  118. '-23:59:59.999999', '-1 days +23:59:59.999999', '-1ns',
  119. '1ns', '-23:59:59.999999999'])
  120. def test_td_from_repr_roundtrip(val):
  121. # round-trip both for string and value
  122. td = Timedelta(val)
  123. assert Timedelta(td.value) == td
  124. # str does not normally display nanos
  125. if not td.nanoseconds:
  126. assert Timedelta(str(td)) == td
  127. assert Timedelta(td._repr_base(format='all')) == td
  128. def test_overflow_on_construction():
  129. # GH#3374
  130. value = Timedelta('1day').value * 20169940
  131. with pytest.raises(OverflowError):
  132. Timedelta(value)
  133. # xref GH#17637
  134. with pytest.raises(OverflowError):
  135. Timedelta(7 * 19999, unit='D')
  136. with pytest.raises(OverflowError):
  137. Timedelta(timedelta(days=13 * 19999))
  138. @pytest.mark.parametrize('fmt,exp', [
  139. ('P6DT0H50M3.010010012S', Timedelta(days=6, minutes=50, seconds=3,
  140. milliseconds=10, microseconds=10,
  141. nanoseconds=12)),
  142. ('P-6DT0H50M3.010010012S', Timedelta(days=-6, minutes=50, seconds=3,
  143. milliseconds=10, microseconds=10,
  144. nanoseconds=12)),
  145. ('P4DT12H30M5S', Timedelta(days=4, hours=12, minutes=30, seconds=5)),
  146. ('P0DT0H0M0.000000123S', Timedelta(nanoseconds=123)),
  147. ('P0DT0H0M0.00001S', Timedelta(microseconds=10)),
  148. ('P0DT0H0M0.001S', Timedelta(milliseconds=1)),
  149. ('P0DT0H1M0S', Timedelta(minutes=1)),
  150. ('P1DT25H61M61S', Timedelta(days=1, hours=25, minutes=61, seconds=61))
  151. ])
  152. def test_iso_constructor(fmt, exp):
  153. assert Timedelta(fmt) == exp
  154. @pytest.mark.parametrize('fmt', [
  155. 'PPPPPPPPPPPP', 'PDTHMS', 'P0DT999H999M999S',
  156. 'P1DT0H0M0.0000000000000S', 'P1DT0H0M00000000000S',
  157. 'P1DT0H0M0.S'])
  158. def test_iso_constructor_raises(fmt):
  159. with pytest.raises(ValueError, match=('Invalid ISO 8601 Duration '
  160. 'format - {}'.format(fmt))):
  161. Timedelta(fmt)
  162. @pytest.mark.parametrize('constructed_td, conversion', [
  163. (Timedelta(nanoseconds=100), '100ns'),
  164. (Timedelta(days=1, hours=1, minutes=1, weeks=1, seconds=1, milliseconds=1,
  165. microseconds=1, nanoseconds=1), 694861001001001),
  166. (Timedelta(microseconds=1) + Timedelta(nanoseconds=1), '1us1ns'),
  167. (Timedelta(microseconds=1) - Timedelta(nanoseconds=1), '999ns'),
  168. (Timedelta(microseconds=1) + 5 * Timedelta(nanoseconds=-2), '990ns')])
  169. def test_td_constructor_on_nanoseconds(constructed_td, conversion):
  170. # GH#9273
  171. assert constructed_td == Timedelta(conversion)
  172. def test_td_constructor_value_error():
  173. with pytest.raises(TypeError):
  174. Timedelta(nanoseconds='abc')