Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adapt parse_date to handle ISO dates #842

Merged
merged 1 commit into from Oct 31, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 17 additions & 3 deletions babel/dates.py
Expand Up @@ -1179,13 +1179,18 @@ class ParseError(ValueError):
def parse_date(string, locale=LC_TIME, format='medium'):
"""Parse a date from a string.

This function uses the date format for the locale as a hint to determine
the order in which the date fields appear in the string.
This function first tries to interpret the string as ISO-8601
date format, then uses the date format for the locale as a hint to
determine the order in which the date fields appear in the string.

>>> parse_date('4/1/04', locale='en_US')
datetime.date(2004, 4, 1)
>>> parse_date('01.04.2004', locale='de_DE')
datetime.date(2004, 4, 1)
>>> parse_date('2004-04-01', locale='en_US')
datetime.date(2004, 4, 1)
>>> parse_date('2004-04-01', locale='de_DE')
datetime.date(2004, 4, 1)

:param string: the string containing the date
:param locale: a `Locale` object or a locale identifier
Expand All @@ -1195,7 +1200,16 @@ def parse_date(string, locale=LC_TIME, format='medium'):
if not numbers:
raise ParseError("No numbers were found in input")

# TODO: try ISO format first?
# we try ISO-8601 format first, meaning similar to formats
# extended YYYY-MM-DD or basic YYYYMMDD
iso_alike = re.match(r'^(\d{4})-?([01]\d)-?([0-3]\d)$',
string, flags=re.ASCII) # allow only ASCII digits
if iso_alike:
try:
return date(*map(int, iso_alike.groups()))
except ValueError:
pass # a locale format might fit better, so let's continue

format_str = get_date_format(format=format, locale=locale).pattern.lower()
year_idx = format_str.index('y')
month_idx = format_str.index('m')
Expand Down