Skip to content

Commit 8c128a3

Browse files
Shengpu Tangjreback
Shengpu Tang
authored andcommitted
BUG: silent overflow in DateTimeArray subtraction (pandas-dev#22508)
1 parent 285eb1e commit 8c128a3

File tree

3 files changed

+37
-1
lines changed

3 files changed

+37
-1
lines changed

doc/source/whatsnew/v0.24.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,7 @@ Datetimelike
582582
- Bug in :class:`DataFrame` comparisons against ``Timestamp``-like objects failing to raise ``TypeError`` for inequality checks with mismatched types (:issue:`8932`,:issue:`22163`)
583583
- Bug in :class:`DataFrame` with mixed dtypes including ``datetime64[ns]`` incorrectly raising ``TypeError`` on equality comparisons (:issue:`13128`,:issue:`22163`)
584584
- Bug in :meth:`DataFrame.eq` comparison against ``NaT`` incorrectly returning ``True`` or ``NaN`` (:issue:`15697`,:issue:`22163`)
585+
- Bug in :class:`DatetimeIndex` subtraction that incorrectly failed to raise `OverflowError` (:issue:`22492`, :issue:`22508`)
585586

586587
Timedelta
587588
^^^^^^^^^

pandas/core/arrays/datetimes.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,8 @@ def _sub_datelike_dti(self, other):
459459

460460
self_i8 = self.asi8
461461
other_i8 = other.asi8
462-
new_values = self_i8 - other_i8
462+
new_values = checked_add_with_arr(self_i8, -other_i8,
463+
arr_mask=self._isnan)
463464
if self.hasnans or other.hasnans:
464465
mask = (self._isnan) | (other._isnan)
465466
new_values[mask] = iNaT

pandas/tests/arithmetic/test_datetime64.py

+34
Original file line numberDiff line numberDiff line change
@@ -1570,6 +1570,40 @@ def test_datetimeindex_sub_timestamp_overflow(self):
15701570
with pytest.raises(OverflowError):
15711571
dtimin - variant
15721572

1573+
def test_datetimeindex_sub_datetimeindex_overflow(self):
1574+
# GH#22492, GH#22508
1575+
dtimax = pd.to_datetime(['now', pd.Timestamp.max])
1576+
dtimin = pd.to_datetime(['now', pd.Timestamp.min])
1577+
1578+
ts_neg = pd.to_datetime(['1950-01-01', '1950-01-01'])
1579+
ts_pos = pd.to_datetime(['1980-01-01', '1980-01-01'])
1580+
1581+
# General tests
1582+
expected = pd.Timestamp.max.value - ts_pos[1].value
1583+
result = dtimax - ts_pos
1584+
assert result[1].value == expected
1585+
1586+
expected = pd.Timestamp.min.value - ts_neg[1].value
1587+
result = dtimin - ts_neg
1588+
assert result[1].value == expected
1589+
1590+
with pytest.raises(OverflowError):
1591+
dtimax - ts_neg
1592+
1593+
with pytest.raises(OverflowError):
1594+
dtimin - ts_pos
1595+
1596+
# Edge cases
1597+
tmin = pd.to_datetime([pd.Timestamp.min])
1598+
t1 = tmin + pd.Timedelta.max + pd.Timedelta('1us')
1599+
with pytest.raises(OverflowError):
1600+
t1 - tmin
1601+
1602+
tmax = pd.to_datetime([pd.Timestamp.max])
1603+
t2 = tmax + pd.Timedelta.min - pd.Timedelta('1us')
1604+
with pytest.raises(OverflowError):
1605+
tmax - t2
1606+
15731607
@pytest.mark.parametrize('names', [('foo', None, None),
15741608
('baz', 'bar', None),
15751609
('bar', 'bar', 'bar')])

0 commit comments

Comments
 (0)