diff options
Diffstat (limited to 'django/utils/dateparse.py')
| -rw-r--r-- | django/utils/dateparse.py | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/django/utils/dateparse.py b/django/utils/dateparse.py index 422f55b9c5..2c749f015c 100644 --- a/django/utils/dateparse.py +++ b/django/utils/dateparse.py @@ -27,6 +27,29 @@ datetime_re = re.compile( r'(?P<tzinfo>Z|[+-]\d{2}(?::?\d{2})?)?$' ) +standard_duration_re = re.compile( + r'^' + r'(?:(?P<days>-?\d+) )?' + r'((?:(?P<hours>\d+):)(?=\d+:\d+))?' + r'(?:(?P<minutes>\d+):)?' + r'(?P<seconds>\d+)' + r'(?:\.(?P<microseconds>\d{1,6})\d{0,6})?' + r'$' +) + +# Support the sections of ISO 8601 date representation that are accepted by +# timedelta +iso8601_duration_re = re.compile( + r'^P' + r'(?:(?P<days>\d+(.\d+)?)D)?' + r'(?:T' + r'(?:(?P<hours>\d+(.\d+)?)H)?' + r'(?:(?P<minutes>\d+(.\d+)?)M)?' + r'(?:(?P<seconds>\d+(.\d+)?)S)?' + r')?' + r'$' +) + def parse_date(value): """Parses a string and return a datetime.date. @@ -84,3 +107,21 @@ def parse_datetime(value): kw = {k: int(v) for k, v in six.iteritems(kw) if v is not None} kw['tzinfo'] = tzinfo return datetime.datetime(**kw) + + +def parse_duration(value): + """Parses a duration string and returns a datetime.timedelta. + + The preferred format for durations in Django is '%d %H:%M:%S.%f'. + + Also supports ISO 8601 representation. + """ + match = standard_duration_re.match(value) + if not match: + match = iso8601_duration_re.match(value) + if match: + kw = match.groupdict() + if kw.get('microseconds'): + kw['microseconds'] = kw['microseconds'].ljust(6, '0') + kw = {k: float(v) for k, v in six.iteritems(kw) if v is not None} + return datetime.timedelta(**kw) |
