Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion babel/dates.py
Original file line number Diff line number Diff line change
Expand Up @@ -1316,13 +1316,19 @@ def parse_date(
# FIXME: this currently only supports numbers, but should also support month
# names, both in the requested locale, and english

if len(numbers) < 3:
raise ParseError(f"Expected three numbers in input, got {len(numbers)}: {string!r}")

year = numbers[indexes['Y']]
year = 2000 + int(year) if len(year) == 2 else int(year)
month = int(numbers[indexes['M']])
day = int(numbers[indexes['D']])
if month > 12:
month, day = day, month
return datetime.date(year, month, day)
try:
return datetime.date(year, month, day)
except ValueError as error:
raise ParseError(f"Could not parse {string!r}: {error}") from error


def parse_time(
Expand Down
15 changes: 15 additions & 0 deletions tests/test_dates.py
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,21 @@ def test_parse_date():
assert dates.parse_date('2004-04-01', locale='sv_SE', format='short') == date(2004, 4, 1)


def test_parse_date_raises_parse_error_instead_of_index_error():
# Strings with fewer than three numbers cannot be matched against the
# locale's numeric date pattern; this used to leak a bare IndexError.
for string, locale in [('Jan 3, 2026', 'en_US'), ('1. Januar 2026', 'de_DE'), ('3 janvier 2026', 'fr_FR')]:
with pytest.raises(dates.ParseError):
dates.parse_date(string, locale=locale)


def test_parse_date_raises_parse_error_on_out_of_range_values():
# Out-of-range fields used to leak the ValueError of datetime.date().
for string in ['99.99.9999', '01.32.2026', '00.01.2026']:
with pytest.raises(dates.ParseError):
dates.parse_date(string, locale='de_DE')


def test_parse_date_custom_format():
assert dates.parse_date('1.4.2024', format='dd.mm.yyyy') == date(2024, 4, 1)
assert dates.parse_date('2024.4.1', format='yyyy.mm.dd') == date(2024, 4, 1)
Expand Down