Detect an invalid calendar date from user text
Also published in our Blogger archive.
Detect an invalid calendar date from user text
A date-shaped string is not necessarily a calendar date. 2024-02-29 is valid because 2024 is a leap year; 2023-02-29 has the same layout but names a day that does not occur. For an input field that accepts ISO calendar dates, date.fromisoformat() provides both parsing and calendar validation. The example prints a normalized ISO date for accepted input and a stable invalid result when parsing raises ValueError.
The try block is deliberately narrow: only conversion of the user text is expected to fail. Once it returns a date, the assertion checks the concrete leap-day result, while the invalid case is asserted through the printed classification. This avoids trying to reproduce month lengths and leap-year rules by hand.
This function is appropriate only when the product contract is an ISO date. It does not accept reduced-precision dates such as a year and month, and an error can mean malformed syntax as well as an impossible date; show a more specific message only if the application separately validates its accepted syntax. A date also uses Python’s idealized proleptic Gregorian calendar, so it is not a historical-calendar validator. date.fromisoformat() was added in Python 3.7; its accepted formats expanded in Python 3.11. Official date.fromisoformat() documentation
AI-assistance disclosure: AI helped draft this educational example; its assertions demonstrate the two fixed inputs only.
from datetime import date
def classify_iso_date(text):
try:
parsed = date.fromisoformat(text)
except ValueError:
return f"{text}: invalid"
return f"{text}: valid ({parsed.isoformat()})"
leap_day = classify_iso_date("2024-02-29")
non_leap_day = classify_iso_date("2023-02-29")
assert leap_day == "2024-02-29: valid (2024-02-29)"
assert non_leap_day == "2023-02-29: invalid"
print(leap_day)
print(non_leap_day)
2024-02-29: valid (2024-02-29)
2023-02-29: invalid