pandas-dev/pandas · error · ValueError
Offset did not decrement date
Error message
Offset {offset} did not decrement date What it means
Raised during backward date-range generation (the offset.n < 0 branch of the generator). After applying the offset to the current date, pandas asserts the result is strictly earlier than the current date; if `offset._apply(cur)` yields a date >= cur, the offset is not actually moving backward and the loop would never terminate, so pandas aborts. This is an infinite-loop guard, not a range-bounds check.
Solutions
- Verify the offset actually steps backward: test `offset._apply(Timestamp(x)) < Timestamp(x)` for representative x in your range before generating.
- If you want a backward range, pass a normal positive offset and let pandas build start->end with start < end, then reverse with [::-1].
- For custom DateOffset subclasses, ensure `_apply`/`apply` strictly decreases the input when `n < 0` (multiply the delta by sign(n)).
- Check that start > end is paired with an offset whose n < 0 (or rely on pandas to negate), and that no anchor snapping returns the same date.
Example fix
# before
rng = date_range('2024-12-31', '2024-01-01', freq=MyNoOpOffset(-1)) # _apply returns same date
# after - step the offset so apply strictly decreases, or reverse a forward range
rng = date_range('2024-01-01', '2024-12-31', freq='MS')[::-1] Defensive patterns
Strategy: validation
Validate before calling
import pandas as pd
def offset_decrements(offset, ts):
return offset._apply(ts) < ts
# before building a backward range
start, end = pd.Timestamp('2024-12-31'), pd.Timestamp('2024-01-01')
if start >= end:
assert offset_decrements(freq, start), f'offset {freq} does not decrement; date_range would fail' Type guard
def is_backward_offset(offset: pd.offsets.BaseOffset, sample: pd.Timestamp) -> bool:
return offset._apply(sample) < sample Try / catch
try:
rng = pd.date_range(start, end, freq=freq)
except ValueError as e:
if 'did not decrement date' in str(e):
rng = pd.date_range(end, start, freq=freq)[::-1] # build forward, reverse
else:
raise Prevention
- For backward ranges, prefer building forward (start < end) and reversing with [::-1].
- Unit-test custom DateOffset subclasses in both directions on boundary dates.
- Confirm the offset's n sign matches the desired direction before constructing date_range.
When it happens
Trigger: Constructing a date_range/DatetimeIndex that iterates backward (start > end with a negative-direction offset, or an offset whose `.n < 0`) where the offset's `_apply` returns a value that does not decrease the timestamp. Happens with custom DateOffset subclasses whose apply is a no-op, with offsets that roll forward to the same anchored point (e.g. some MonthEnd / YearBegin anchorings on boundary dates), or with semi-monthend offsets that snap instead of step.
Common situations: Custom DateOffset subclasses that forget to move the date in one direction; calling `date_range(start, end, freq=<negative offset>)` where start > end but the offset increments; using `pd.offsets.SemiMonthEnd(-1)` or similar negative offsets on dates where the rule resolves to the same day; version upgrades that changed anchor semantics for BusinessHour/CustomBusinessHour.
Related errors
- Offset did not increment date
- Inferred time zone not equal to passed time zone
- Start and end cannot both be tz-aware with different…
- abs(axis) must be less than ndim
- Accumulation not supported for
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/cf130195fc75d099.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/arrays/datetimes.py:3288
next_date = offset._apply(cur)
next_date = next_date.as_unit(unit)
if next_date <= cur:
raise ValueError(f"Offset {offset} did not increment date")
cur = next_date
else:
while cur >= end:
yield cur
if cur == end:
# GH#24252 avoid overflows by not performing the addition
# in offset.apply unless we have to
break
# faster than cur + offset
next_date = offset._apply(cur)
next_date = next_date.as_unit(unit)
if next_date >= cur:
raise ValueError(f"Offset {offset} did not decrement date")
cur = next_date
View on GitHub (pinned to 3b7651241d)