RustPython/RustPython · error · OverflowError
result out of range
Error message
result out of range
What it means
Raised by date.__add__ when adding a timedelta moves the result outside the representable date range (year 1-01-01 through year 9999-12-31, i.e. ordinals 1 to date.max.toordinal()). Dates are stored as proleptic Gregorian ordinals and cannot wrap around or go below day 1, so any addition whose target ordinal is <= 0 or > _MAXORDINAL is rejected with OverflowError instead of producing an invalid date.
Source
Thrown at Lib/_pydatetime.py:1218
y, m, d = self._year, self._month, self._day
y2, m2, d2 = other._year, other._month, other._day
return _cmp((y, m, d), (y2, m2, d2))
def __hash__(self):
"Hash."
if self._hashcode == -1:
self._hashcode = hash(self._getstate())
return self._hashcode
# Computations
def __add__(self, other):
"Add a date to a timedelta."
if isinstance(other, timedelta):
o = self.toordinal() + other.days
if 0 < o <= _MAXORDINAL:
return type(self).fromordinal(o)
raise OverflowError("result out of range")
return NotImplemented
__radd__ = __add__
def __sub__(self, other):
"""Subtract two dates, or a date and a timedelta."""
if isinstance(other, timedelta):
return self + timedelta(-other.days)
if isinstance(other, date):
days1 = self.toordinal()
days2 = other.toordinal()
return timedelta(days1 - days2)
return NotImplemented
def weekday(self):
"Return day of the week, where Monday == 0 ... Sunday == 6."
return (self.toordinal() + 6) % 7
View on GitHub (pinned to aaeab4f754)
Solutions
- Validate the target ordinal before adding: 1 <= d.toordinal() + delta.days <= date.max.toordinal(); reject or clamp the input if outside.
- Catch OverflowError at the boundary and clamp to date.min/date.max or surface a user-facing 'date out of range' message.
- Bound the offset itself (cap timedelta.days) when it originates from user input or configuration.
- If dates outside year 1..9999 are genuinely needed, switch representation (integer year/month/day or a third-party date type) instead of fighting the limit.
Example fix
// before
d = start + timedelta(days=offset) # OverflowError when start is near date.max
// after
from datetime import date, timedelta
def add_days(d: date, offset: int) -> date:
ordinal = d.toordinal() + offset
if not 1 <= ordinal <= date.max.toordinal():
raise OverflowError(f'{offset} days from {d} leaves year 1..9999')
return d + timedelta(days=offset) Defensive patterns
Strategy: validation
Validate before calling
from datetime import date, timedelta
def safe_date_add(d: date, delta: timedelta) -> date:
target = d.toordinal() + delta.days
if not 1 <= target <= date.max.toordinal():
raise OverflowError(f'{delta} moves {d} outside year 1..9999')
return d + delta Try / catch
try:
result = d + delta
except OverflowError:
result = date.max # or reject the request with a user-facing error Prevention
- Check d.toordinal() + delta.days against 1..date.max.toordinal() before adding.
- Cap user-supplied day/week offsets at ingestion.
- Give day-stepping loops an explicit date.max stop condition.
- Remember timedelta.days truncates toward zero for sub-day deltas.
When it happens
Trigger: date.max + timedelta(days=1); date(1, 1, 1) + timedelta(days=-1); date(9999, 12, 31) + timedelta(weeks=2); day-stepping loops (d += timedelta(days=1)) that run past the horizon; large user-supplied offsets such as timedelta(days=400000) added to arbitrary dates.
Common situations: Scheduled-event generators iterating forward without a stop check; billing or maturity date math that adds years as big day counts; porting arithmetic from systems that clamp or wrap dates; property/fuzz tests adding random timedeltas to random dates.
Related errors
- month must be in 1..12, not {month}
- day {day} must be in range 1..{dim} for month {month} in yea
- unsupported type for timedelta {name} component: {type(value
- timedelta # of days is too large: %d
- date argument must be a date instance
AI-assisted analysis of RustPython/RustPython@aaeab4f754 (2026-08-17).
Data as JSON: /api/errors/68205f7bcc119522.
Report an issue: GitHub.