diff options
| author | Marc Tamlyn <marc.tamlyn@gmail.com> | 2014-07-24 13:57:24 +0100 |
|---|---|---|
| committer | Marc Tamlyn <marc.tamlyn@gmail.com> | 2014-12-20 18:28:29 +0000 |
| commit | 57554442fe3e209c135e15dda4ea45123e579e58 (patch) | |
| tree | 0ef2cb0e3048d13b82e4c7e81192df6124556a44 /django/utils/dateparse.py | |
| parent | a3d96bee36040975ded8e3bf02e33e48d06f1f16 (diff) | |
Fixed #2443 -- Added DurationField.
A field for storing periods of time - modeled in Python by timedelta. It
is stored in the native interval data type on PostgreSQL and as a bigint
of microseconds on other backends.
Also includes significant changes to the internals of time related maths
in expressions, including the removal of DateModifierNode.
Thanks to Tim and Josh in particular for reviews.
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) |
