Skip to content

Commit e91f46d

Browse files
Backport PR #32499: Better error message for OOB result (#32605)
1 parent 41181e6 commit e91f46d

File tree

3 files changed

+27
-1
lines changed

3 files changed

+27
-1
lines changed

doc/source/whatsnew/v1.0.2.rst

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ Bug fixes
6565

6666
- Bug in :meth:`DataFrame.reindex` and :meth:`Series.reindex` when reindexing with a tz-aware index (:issue:`26683`)
6767
- Bug where :func:`to_datetime` would raise when passed ``pd.NA`` (:issue:`32213`)
68+
- Improved error message when subtracting two :class:`Timestamp` that result in an out-of-bounds :class:`Timedelta` (:issue:`31774`)
6869

6970
**Categorical**
7071

pandas/_libs/tslibs/c_timestamp.pyx

+12-1
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,10 @@ cdef class _Timestamp(datetime):
286286
# coerce if necessary if we are a Timestamp-like
287287
if (PyDateTime_Check(self)
288288
and (PyDateTime_Check(other) or is_datetime64_object(other))):
289+
# both_timestamps is to determine whether Timedelta(self - other)
290+
# should raise the OOB error, or fall back returning a timedelta.
291+
both_timestamps = (isinstance(other, _Timestamp) and
292+
isinstance(self, _Timestamp))
289293
if isinstance(self, _Timestamp):
290294
other = type(self)(other)
291295
else:
@@ -301,7 +305,14 @@ cdef class _Timestamp(datetime):
301305
from pandas._libs.tslibs.timedeltas import Timedelta
302306
try:
303307
return Timedelta(self.value - other.value)
304-
except (OverflowError, OutOfBoundsDatetime):
308+
except (OverflowError, OutOfBoundsDatetime) as err:
309+
if isinstance(other, _Timestamp):
310+
if both_timestamps:
311+
raise OutOfBoundsDatetime(
312+
"Result is too large for pandas.Timedelta. Convert inputs "
313+
"to datetime.datetime with 'Timestamp.to_pydatetime()' "
314+
"before subtracting."
315+
) from err
305316
pass
306317
elif is_datetime64_object(self):
307318
# GH#28286 cython semantics for __rsub__, `other` is actually

pandas/tests/scalar/timestamp/test_arithmetic.py

+14
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import numpy as np
44
import pytest
55

6+
from pandas.errors import OutOfBoundsDatetime
7+
68
from pandas import Timedelta, Timestamp
79

810
from pandas.tseries import offsets
@@ -60,6 +62,18 @@ def test_overflow_offset_raises(self):
6062
with pytest.raises(OverflowError, match=msg):
6163
stamp - offset_overflow
6264

65+
def test_overflow_timestamp_raises(self):
66+
# https://github.com/pandas-dev/pandas/issues/31774
67+
msg = "Result is too large"
68+
a = Timestamp("2101-01-01 00:00:00")
69+
b = Timestamp("1688-01-01 00:00:00")
70+
71+
with pytest.raises(OutOfBoundsDatetime, match=msg):
72+
a - b
73+
74+
# but we're OK for timestamp and datetime.datetime
75+
assert (a - b.to_pydatetime()) == (a.to_pydatetime() - b)
76+
6377
def test_delta_preserve_nanos(self):
6478
val = Timestamp(1337299200000000123)
6579
result = val + timedelta(1)

0 commit comments

Comments
 (0)