test_arithmetic.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. # -*- coding: utf-8 -*-
  2. from datetime import datetime, timedelta
  3. import numpy as np
  4. import pytest
  5. from pandas.compat import long
  6. from pandas import Timedelta, Timestamp
  7. import pandas.util.testing as tm
  8. from pandas.tseries import offsets
  9. from pandas.tseries.frequencies import to_offset
  10. class TestTimestampArithmetic(object):
  11. def test_overflow_offset(self):
  12. # no overflow expected
  13. stamp = Timestamp("2000/1/1")
  14. offset_no_overflow = to_offset("D") * 100
  15. expected = Timestamp("2000/04/10")
  16. assert stamp + offset_no_overflow == expected
  17. assert offset_no_overflow + stamp == expected
  18. expected = Timestamp("1999/09/23")
  19. assert stamp - offset_no_overflow == expected
  20. def test_overflow_offset_raises(self):
  21. # xref https://github.com/statsmodels/statsmodels/issues/3374
  22. # ends up multiplying really large numbers which overflow
  23. stamp = Timestamp('2017-01-13 00:00:00', freq='D')
  24. offset_overflow = 20169940 * offsets.Day(1)
  25. msg = ("the add operation between "
  26. r"\<-?\d+ \* Days\> and \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} "
  27. "will overflow")
  28. with pytest.raises(OverflowError, match=msg):
  29. stamp + offset_overflow
  30. with pytest.raises(OverflowError, match=msg):
  31. offset_overflow + stamp
  32. with pytest.raises(OverflowError, match=msg):
  33. stamp - offset_overflow
  34. # xref https://github.com/pandas-dev/pandas/issues/14080
  35. # used to crash, so check for proper overflow exception
  36. stamp = Timestamp("2000/1/1")
  37. offset_overflow = to_offset("D") * 100 ** 25
  38. with pytest.raises(OverflowError, match=msg):
  39. stamp + offset_overflow
  40. with pytest.raises(OverflowError, match=msg):
  41. offset_overflow + stamp
  42. with pytest.raises(OverflowError, match=msg):
  43. stamp - offset_overflow
  44. def test_delta_preserve_nanos(self):
  45. val = Timestamp(long(1337299200000000123))
  46. result = val + timedelta(1)
  47. assert result.nanosecond == val.nanosecond
  48. def test_timestamp_sub_datetime(self):
  49. dt = datetime(2013, 10, 12)
  50. ts = Timestamp(datetime(2013, 10, 13))
  51. assert (ts - dt).days == 1
  52. assert (dt - ts).days == -1
  53. def test_addition_subtraction_types(self):
  54. # Assert on the types resulting from Timestamp +/- various date/time
  55. # objects
  56. dt = datetime(2014, 3, 4)
  57. td = timedelta(seconds=1)
  58. # build a timestamp with a frequency, since then it supports
  59. # addition/subtraction of integers
  60. ts = Timestamp(dt, freq='D')
  61. with tm.assert_produces_warning(FutureWarning):
  62. # GH#22535 add/sub with integers is deprecated
  63. assert type(ts + 1) == Timestamp
  64. assert type(ts - 1) == Timestamp
  65. # Timestamp + datetime not supported, though subtraction is supported
  66. # and yields timedelta more tests in tseries/base/tests/test_base.py
  67. assert type(ts - dt) == Timedelta
  68. assert type(ts + td) == Timestamp
  69. assert type(ts - td) == Timestamp
  70. # Timestamp +/- datetime64 not supported, so not tested (could possibly
  71. # assert error raised?)
  72. td64 = np.timedelta64(1, 'D')
  73. assert type(ts + td64) == Timestamp
  74. assert type(ts - td64) == Timestamp
  75. def test_addition_subtraction_preserve_frequency(self):
  76. ts = Timestamp('2014-03-05', freq='D')
  77. td = timedelta(days=1)
  78. original_freq = ts.freq
  79. with tm.assert_produces_warning(FutureWarning):
  80. # GH#22535 add/sub with integers is deprecated
  81. assert (ts + 1).freq == original_freq
  82. assert (ts - 1).freq == original_freq
  83. assert (ts + td).freq == original_freq
  84. assert (ts - td).freq == original_freq
  85. td64 = np.timedelta64(1, 'D')
  86. assert (ts + td64).freq == original_freq
  87. assert (ts - td64).freq == original_freq