datetime.MINYEAR / MAXYEAR
Four-digit years only: 0001-01-01 to 9999-12-31. Constructing outside that raises ValueError, arithmetic that leaves it raises OverflowError.
Common call
MINYEAR <= year <= MAXYEAR
Returns
True for every year a date can hold
Replaces
Hard-coded 1 and 9999 in validation code
Watch out
No year 0 and no BC dates
MINYEAR = 1 · MAXYEAR = 9999
→ int
Demo
Live evaluation
Try years around the edges. The error type tells you which check failed.
Try:
Inputs
yearinta year
Code
from datetime import date, MINYEAR, MAXYEAR (MINYEAR <= 9999 <= MAXYEAR, date(9999, 1, 1))
Result
(True, datetime.date(9999, 1, 1))
Construction checks the year first and reports it: "year 10000 is out of range", "year 0 is out of range". Going past the end by arithmetic is a different error — OverflowError: date value out of range.
Common patterns
Validate user input before constructing
Give a friendly message instead of the raw ValueError.
from datetime import MINYEAR, MAXYEAR if not MINYEAR <= year <= MAXYEAR: raise ValueError(f'year must be between {MINYEAR} and {MAXYEAR}')
A far-future sentinel
For "never expires", prefer date.max over an invented year.
from datetime import date expires = date.max
Examples
1. The values
from datetime import MINYEAR, MAXYEAR
(MINYEAR, MAXYEAR)
Returns
(1, 9999)2. Year 0 does not exist
from datetime import date
date(0, 1, 1)
Returns
ValueError: year 0 is out of range3. Neither does 10000
from datetime import date, MAXYEAR
date(MAXYEAR + 1, 1, 1)
Returns
ValueError: year 10000 is out of range4. Arithmetic overflow
from datetime import date, timedelta, MAXYEAR
date(MAXYEAR, 12, 31) + timedelta(days=1)
Returns
OverflowError: date value out of range5. Ordinal 1 is MINYEAR-01-01
from datetime import date, MINYEAR
date(MINYEAR, 1, 1).toordinal()
Returns
1Pitfalls
1. Using year 0 or 10000 as a placeholder
Neither is a valid year. Use None for "unknown", or date.min / date.max for open ranges.
year 0
from datetime import date unknown = date(0, 1, 1)
ValueError: year 0 is out of range
date.min
from datetime import date unknown = date.min unknown
datetime.date(1, 1, 1)
2. Timestamps near the edge overflow
Adding an offset or a margin to a max value overflows. Check before adding.
max + a day
from datetime import datetime, timedelta datetime.max + timedelta(days=1)
OverflowError: date value out of range
guard
from datetime import datetime, timedelta end = datetime.max end if end > datetime.max - timedelta(days=1) else end + timedelta(days=1)
datetime.datetime(9999, 12, 31, 23, 59, 59, 999999)
When to use
Use it
- Validating year inputs
- Documenting the supported range of your own API
Reach for something else
- Historical or astronomical dates outside 1..9999 → another library (e.g. astropy.time)
Notes
CPython impl
MINYEAR and MAXYEAR are module-level ints set in Modules/_datetimemodule.c
Errors
Constructor: ValueError "year N is out of range". Arithmetic: OverflowError "date value out of range"
Related
date.min / date.max / datetime.min / datetime.max are the matching objects
FAQ
No. MINYEAR is 1 and MAXYEAR is 9999; there is no year 0 and no negative year. Use a specialised library for astronomical or historical ranges.