diff --git a/doc/source/whatsnew/v1.3.0.rst b/doc/source/whatsnew/v1.3.0.rst index b061c4040096e..eed712ae7de0f 100644 --- a/doc/source/whatsnew/v1.3.0.rst +++ b/doc/source/whatsnew/v1.3.0.rst @@ -233,6 +233,7 @@ Datetimelike - Bug in :meth:`DatetimeIndex.intersection`, :meth:`DatetimeIndex.symmetric_difference`, :meth:`PeriodIndex.intersection`, :meth:`PeriodIndex.symmetric_difference` always returning object-dtype when operating with :class:`CategoricalIndex` (:issue:`38741`) - Bug in :meth:`Series.where` incorrectly casting ``datetime64`` values to ``int64`` (:issue:`37682`) - Bug in :class:`Categorical` incorrectly typecasting ``datetime`` object to ``Timestamp`` (:issue:`38878`) +- Bug in :func:`date_range` incorrectly creating :class:`DatetimeIndex` containing ``NaT`` instead of raising ``OutOfBoundsDatetime`` in corner cases (:issue:`24124`) Timedelta ^^^^^^^^^ diff --git a/pandas/core/arrays/_ranges.py b/pandas/core/arrays/_ranges.py index 14b442bf71080..c001c57ffe757 100644 --- a/pandas/core/arrays/_ranges.py +++ b/pandas/core/arrays/_ranges.py @@ -7,7 +7,13 @@ import numpy as np -from pandas._libs.tslibs import BaseOffset, OutOfBoundsDatetime, Timedelta, Timestamp +from pandas._libs.tslibs import ( + BaseOffset, + OutOfBoundsDatetime, + Timedelta, + Timestamp, + iNaT, +) def generate_regular_range( @@ -150,7 +156,12 @@ def _generate_range_overflow_safe_signed( addend = np.int64(periods) * np.int64(stride) try: # easy case with no overflows - return np.int64(endpoint) + addend + result = np.int64(endpoint) + addend + if result == iNaT: + # Putting this into a DatetimeArray/TimedeltaArray + # would incorrectly be interpreted as NaT + raise OverflowError + return result except (FloatingPointError, OverflowError): # with endpoint negative and addend positive we risk # FloatingPointError; with reversed signed we risk OverflowError diff --git a/pandas/tests/indexes/datetimes/test_date_range.py b/pandas/tests/indexes/datetimes/test_date_range.py index 7c70b58318a11..b8def8072a3b7 100644 --- a/pandas/tests/indexes/datetimes/test_date_range.py +++ b/pandas/tests/indexes/datetimes/test_date_range.py @@ -15,7 +15,7 @@ import pandas.util._test_decorators as td import pandas as pd -from pandas import DatetimeIndex, Timestamp, bdate_range, date_range, offsets +from pandas import DatetimeIndex, Timedelta, Timestamp, bdate_range, date_range, offsets import pandas._testing as tm from pandas.core.arrays.datetimes import generate_range @@ -76,6 +76,13 @@ def test_date_range_timestamp_equiv_preserve_frequency(self): class TestDateRanges: + def test_date_range_near_implementation_bound(self): + # GH#??? + freq = Timedelta(1) + + with pytest.raises(OutOfBoundsDatetime, match="Cannot generate range with"): + date_range(end=Timestamp.min, periods=2, freq=freq) + def test_date_range_nat(self): # GH#11587 msg = "Neither `start` nor `end` can be NaT"