diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt index d0aa156cf5059..7dc86b9c1e608 100644 --- a/doc/source/whatsnew/v0.24.0.txt +++ b/doc/source/whatsnew/v0.24.0.txt @@ -914,6 +914,7 @@ Datetimelike - Bug in rounding methods of :class:`DatetimeIndex` (:meth:`~DatetimeIndex.round`, :meth:`~DatetimeIndex.ceil`, :meth:`~DatetimeIndex.floor`) and :class:`Timestamp` (:meth:`~Timestamp.round`, :meth:`~Timestamp.ceil`, :meth:`~Timestamp.floor`) could give rise to loss of precision (:issue:`22591`) - Bug in :func:`to_datetime` with an :class:`Index` argument that would drop the ``name`` from the result (:issue:`21697`) - Bug in :class:`PeriodIndex` where adding or subtracting a :class:`timedelta` or :class:`Tick` object produced incorrect results (:issue:`22988`) +- Bug in :func:`date_range` when decrementing a start date to a past end date by a negative frequency (:issue:`23270`) Timedelta ^^^^^^^^^ diff --git a/pandas/tests/indexes/datetimes/test_date_range.py b/pandas/tests/indexes/datetimes/test_date_range.py index 7481c4a710083..c05c80df29dac 100644 --- a/pandas/tests/indexes/datetimes/test_date_range.py +++ b/pandas/tests/indexes/datetimes/test_date_range.py @@ -510,6 +510,16 @@ def test_timezone_comparaison_assert(self): with tm.assert_raises_regex(AssertionError, msg): date_range(start, periods=2, tz='Europe/Berlin') + def test_negative_non_tick_frequency_descending_dates(self, + tz_aware_fixture): + # GH 23270 + tz = tz_aware_fixture + result = pd.date_range(start='2011-06-01', end='2011-01-01', + freq='-1MS', tz=tz) + expected = pd.date_range(end='2011-06-01', start='2011-01-01', + freq='1MS', tz=tz)[::-1] + tm.assert_index_equal(result, expected) + class TestGenRangeGeneration(object): diff --git a/pandas/tseries/offsets.py b/pandas/tseries/offsets.py index e6d73fc45c502..650c4d5b21d7f 100644 --- a/pandas/tseries/offsets.py +++ b/pandas/tseries/offsets.py @@ -2388,7 +2388,7 @@ def generate_range(start=None, end=None, periods=None, elif end and not offset.onOffset(end): end = offset.rollback(end) - if periods is None and end < start: + if periods is None and end < start and offset.n >= 0: end = None periods = 0