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. Raise ValueError if the input is well formatted but not a valid date.
Return None if the input isn't well formatted. Return None if the input isn't well formatted.
""" """
match = date_re.match(value) try:
if match: return datetime.date.fromisoformat(value)
except ValueError:
if match := date_re.match(value):
kw = {k: int(v) for k, v in match.groupdict().items()} kw = {k: int(v) for k, v in match.groupdict().items()}
return datetime.date(**kw) 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 Return None if the input isn't well formatted, in particular if it
contains an offset. contains an offset.
""" """
match = time_re.match(value) try:
if match: # 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 = match.groupdict()
kw['microsecond'] = kw['microsecond'] and kw['microsecond'].ljust(6, '0') 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} 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. Raise ValueError if the input is well formatted but not a valid datetime.
Return None if the input isn't well formatted. Return None if the input isn't well formatted.
""" """
match = datetime_re.match(value) try:
if match: return datetime.datetime.fromisoformat(value)
except ValueError:
if match := datetime_re.match(value):
kw = match.groupdict() kw = match.groupdict()
kw['microsecond'] = kw['microsecond'] and kw['microsecond'].ljust(6, '0') kw['microsecond'] = kw['microsecond'] and kw['microsecond'].ljust(6, '0')
tzinfo = kw.pop('tzinfo') tzinfo = kw.pop('tzinfo')
@ -118,8 +128,7 @@ def parse_datetime(value):
offset = -offset offset = -offset
tzinfo = get_fixed_timezone(offset) tzinfo = get_fixed_timezone(offset)
kw = {k: int(v) for k, v in kw.items() if v is not None} kw = {k: int(v) for k, v in kw.items() if v is not None}
kw['tzinfo'] = tzinfo return datetime.datetime(**kw, tzinfo=tzinfo)
return datetime.datetime(**kw)
def parse_duration(value): def parse_duration(value):