TheAlgorithms/Python · error · ValueError
Date must be between 1 - 31
Error message
Date must be between 1 - 31
What it means
Raised by zeller(date_input) in maths/zellers_congruence.py when the two-digit day parsed from date_input[3:5] is not in 1..31. Like the other checks it is positional, so any upstream misalignment (wrong separator count, missing zero padding) can surface here as an out-of-range day. Note the function later cross-checks the real calendar with datetime.date(y, m, d), so impossible days like 02-31 also fail, though with datetime's own ValueError.
Source
Thrown at maths/zellers_congruence.py:106
if not 0 < len(date_input) < 11:
raise ValueError("Must be 10 characters long")
# Get month
m: int = int(date_input[0] + date_input[1])
# Validate
if not 0 < m < 13:
raise ValueError("Month must be between 1 - 12")
sep_1: str = date_input[2]
# Validate
if sep_1 not in ["-", "/"]:
raise ValueError("Date separator must be '-' or '/'")
# Get day
d: int = int(date_input[3] + date_input[4])
# Validate
if not 0 < d < 32:
raise ValueError("Date must be between 1 - 31")
# Get second separator
sep_2: str = date_input[5]
# Validate
if sep_2 not in ["-", "/"]:
raise ValueError("Date separator must be '-' or '/'")
# Get year
y: int = int(date_input[6] + date_input[7] + date_input[8] + date_input[9])
# Arbitrary year range
if not 45 < y < 8500:
raise ValueError(
"Year out of range. There has to be some sort of limit...right?"
)
# Get datetime obj for validation
dt_ck = datetime.date(int(y), int(m), int(d))
View on GitHub (pinned to f5988cc097)
Solutions
- Normalize to MM-DD-YYYY via strftime('%m-%d-%Y') so the day is always valid and correctly positioned.
- Validate input with datetime.strptime(s, '%m-%d-%Y') before calling zeller to get a precise, well-known error message.
- If accepting multiple formats, parse to a date object first, then format to the one shape zeller accepts.
Example fix
# before
zeller(raw) # raw = '31-01-2010' style or malformed
# after
from datetime import datetime
d = datetime.strptime(raw, '%d-%m-%Y') # parse what you actually receive
zeller(d.strftime('%m-%d-%Y')) Defensive patterns
Strategy: validation
Validate before calling
from datetime import datetime
def valid_mmddyyyy(s: str) -> bool:
try:
datetime.strptime(s, '%m-%d-%Y')
return True
except ValueError:
return False Try / catch
try:
day = zeller(s)
except ValueError as e:
# covers day range plus datetime's own calendar check (e.g. 02-31)
return f'invalid date {s!r}: {e}' Prevention
- Zero-pad single-digit days and months (the parser is positional).
- Validate with strptime('%m-%d-%Y') first for precise messages.
When it happens
Trigger: Calling zeller('01-33-2010') (day 33); passing DD-MM-YYYY input where the day lands in the month slot or vice versa; '01-.4-2010' where the day is non-numeric raises int() ValueError instead.
Common situations: Day/month transposition; unpadded single-digit days shifting positions ('1-3-2010'); user typos or scraped text with malformed dates.
Related errors
- Must be 10 characters long
- Month must be between 1 - 12
- Date separator must be '-' or '/'
- Power cannot be negative in any electrical/electronics syste
- One and only one argument must be 0
AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14).
Data as JSON: /api/errors/92ef4e6c27f37154.
Report an issue: GitHub.