Opened 8 hours ago
Last modified 5 hours ago
#36747 new Bug
parse_duration() fails to parse valid ISO-8601 durations including years, months, and weeks due to incorrect regex — at Version 1
| Reported by: | florianvazelle | Owned by: | |
|---|---|---|---|
| Component: | Uncategorized | Version: | 5.2 |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Description
django.utils.dateparse.parse_duration() claims to support ISO-8601 duration strings, but the current implementation only handles the PnDTnHnMnS subset. Valid ISO-8601 components such as years (Y), months (M), and weeks (W) are not supported.
The internal regex used for ISO-8601 durations:
iso8601_duration_re = _lazy_re_compile(
r"^(?P<sign>[-+]?)"
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"$"
)
This means Django currently rejects valid duration strings such as:
P1Y2M P3W P1Y P2M10DT2H
Despite the documentation suggesting ISO-8601 support, these forms cannot be parsed.
Steps to Reproduce
from django.utils.dateparse import parse_duration
parse_duration("P1Y") # returns None
parse_duration("P2M") # returns None
parse_duration("P3W") # returns None
parse_duration("P1Y2M3DT4H") # returns None
Expected Behavior
parse_duration() should parse all valid ISO-8601 durations that can be represented as timedelta, including:
PnWPnYnMnD- ...
Django should capture each calendar unit, or clearly state limitations.