# -*- coding: utf-8 -*- from datetime import datetime, timedelta import numpy as np import pytest from pandas.compat import long from pandas import Timedelta, Timestamp import pandas.util.testing as tm from pandas.tseries import offsets from pandas.tseries.frequencies import to_offset class TestTimestampArithmetic(object): def test_overflow_offset(self): # no overflow expected stamp = Timestamp("2000/1/1") offset_no_overflow = to_offset("D") * 100 expected = Timestamp("2000/04/10") assert stamp + offset_no_overflow == expected assert offset_no_overflow + stamp == expected expected = Timestamp("1999/09/23") assert stamp - offset_no_overflow == expected def test_overflow_offset_raises(self): # xref https://github.com/statsmodels/statsmodels/issues/3374 # ends up multiplying really large numbers which overflow stamp = Timestamp('2017-01-13 00:00:00', freq='D') offset_overflow = 20169940 * offsets.Day(1) msg = ("the add operation between " r"\<-?\d+ \* Days\> and \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} " "will overflow") with pytest.raises(OverflowError, match=msg): stamp + offset_overflow with pytest.raises(OverflowError, match=msg): offset_overflow + stamp with pytest.raises(OverflowError, match=msg): stamp - offset_overflow # xref https://github.com/pandas-dev/pandas/issues/14080 # used to crash, so check for proper overflow exception stamp = Timestamp("2000/1/1") offset_overflow = to_offset("D") * 100 ** 25 with pytest.raises(OverflowError, match=msg): stamp + offset_overflow with pytest.raises(OverflowError, match=msg): offset_overflow + stamp with pytest.raises(OverflowError, match=msg): stamp - offset_overflow def test_delta_preserve_nanos(self): val = Timestamp(long(1337299200000000123)) result = val + timedelta(1) assert result.nanosecond == val.nanosecond def test_timestamp_sub_datetime(self): dt = datetime(2013, 10, 12) ts = Timestamp(datetime(2013, 10, 13)) assert (ts - dt).days == 1 assert (dt - ts).days == -1 def test_addition_subtraction_types(self): # Assert on the types resulting from Timestamp +/- various date/time # objects dt = datetime(2014, 3, 4) td = timedelta(seconds=1) # build a timestamp with a frequency, since then it supports # addition/subtraction of integers ts = Timestamp(dt, freq='D') with tm.assert_produces_warning(FutureWarning): # GH#22535 add/sub with integers is deprecated assert type(ts + 1) == Timestamp assert type(ts - 1) == Timestamp # Timestamp + datetime not supported, though subtraction is supported # and yields timedelta more tests in tseries/base/tests/test_base.py assert type(ts - dt) == Timedelta assert type(ts + td) == Timestamp assert type(ts - td) == Timestamp # Timestamp +/- datetime64 not supported, so not tested (could possibly # assert error raised?) td64 = np.timedelta64(1, 'D') assert type(ts + td64) == Timestamp assert type(ts - td64) == Timestamp def test_addition_subtraction_preserve_frequency(self): ts = Timestamp('2014-03-05', freq='D') td = timedelta(days=1) original_freq = ts.freq with tm.assert_produces_warning(FutureWarning): # GH#22535 add/sub with integers is deprecated assert (ts + 1).freq == original_freq assert (ts - 1).freq == original_freq assert (ts + td).freq == original_freq assert (ts - td).freq == original_freq td64 = np.timedelta64(1, 'D') assert (ts + td64).freq == original_freq assert (ts - td64).freq == original_freq