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 florianvazelle)

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:

  • PnW
  • PnYnMnD
  • ...

Django should capture each calendar unit, or clearly state limitations.

Change History (1)

comment:1 by florianvazelle, 8 hours ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top