Fixed #32892 -- Optimized django.utils.dateparse functions by using fromisoformat().

This commit is contained in:
Keryn Knight 2021-07-01 12:05:41 +01:00 committed by Mariusz Felisiak
parent 857320e9e0
commit f35ab74752
1 changed files with 35 additions and 26 deletions

View File

@ -72,8 +72,10 @@ def parse_date(value):
Raise ValueError if the input is well formatted but not a valid date.
Return None if the input isn't well formatted.
"""
match = date_re.match(value)
if match:
try:
return datetime.date.fromisoformat(value)
except ValueError:
if match := date_re.match(value):
kw = {k: int(v) for k, v in match.groupdict().items()}
return datetime.date(**kw)
@ -87,8 +89,14 @@ def parse_time(value):
Return None if the input isn't well formatted, in particular if it
contains an offset.
"""
match = time_re.match(value)
if match:
try:
# The fromisoformat() method takes time zone info into account and
# returns a time with a tzinfo component, if possible. However, there
# are no circumstances where aware datetime.time objects make sense, so
# remove the time zone offset.
return datetime.time.fromisoformat(value).replace(tzinfo=None)
except ValueError:
if match := time_re.match(value):
kw = match.groupdict()
kw['microsecond'] = kw['microsecond'] and kw['microsecond'].ljust(6, '0')
kw = {k: int(v) for k, v in kw.items() if v is not None}
@ -104,8 +112,10 @@ def parse_datetime(value):
Raise ValueError if the input is well formatted but not a valid datetime.
Return None if the input isn't well formatted.
"""
match = datetime_re.match(value)
if match:
try:
return datetime.datetime.fromisoformat(value)
except ValueError:
if match := datetime_re.match(value):
kw = match.groupdict()
kw['microsecond'] = kw['microsecond'] and kw['microsecond'].ljust(6, '0')
tzinfo = kw.pop('tzinfo')
@ -118,8 +128,7 @@ def parse_datetime(value):
offset = -offset
tzinfo = get_fixed_timezone(offset)
kw = {k: int(v) for k, v in kw.items() if v is not None}
kw['tzinfo'] = tzinfo
return datetime.datetime(**kw)
return datetime.datetime(**kw, tzinfo=tzinfo)
def parse_duration(value):