Opened 4 years ago

Closed 4 years ago

#32269 closed Bug (fixed)

parse_duration() ISO string sign is ignored when the timedelta only has days

Reported by: Hanno Owned by: starryrbs
Component: Utilities Version: 3.1
Severity: Normal Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I'm pretty sure that this is a bug even though I'm not an expert on the ISO 8601 standard. The sign of a timedelta string will be ignored by django.utils.dateparse.parse_duration if the input string only contains days. Compare the following (notice the minus signs):

In [4]: timedelta(days=-1)
Out[4]: datetime.timedelta(days=-1)

In [5]: td = timedelta(days=-1)

In [6]: duration_iso_string(td)
Out[6]: '-P1DT00H00M00S'

In [7]: parse_duration(duration_iso_string(td))
Out[7]: datetime.timedelta(days=1)  # <-- Why is this 1 and not -1?

In [8]: td = timedelta(days=-1, microseconds=1)

In [9]: duration_iso_string(td)
Out[9]: '-P0DT23H59M59.999999S'

In [10]: parse_duration(duration_iso_string(td))
Out[10]: datetime.timedelta(days=-1, microseconds=1)

I guess the problem is in django/utils/dateparse.py line 147 that reads return days + sign * datetime.timedelta(**kw).
However, if datetime.timedelta(**kw) ends up being zero (timedelta(0)) then the sign multiplication ends up in zero, not -0. This is just a preliminary quick look though and maybe the problem is something else.

Change History (5)

comment:1 by Mariusz Felisiak, 4 years ago

Triage Stage: UnreviewedAccepted

Great catch. Would you like to prepare a patch?

comment:2 by Hanno, 4 years ago

I can try! Hopefully I can find the time.

comment:3 by Hanno, 4 years ago

Owner: changed from nobody to Hanno
Status: newassigned

comment:4 by Mariusz Felisiak, 4 years ago

Has patch: set
Owner: changed from Hanno to starryrbs
Triage Stage: AcceptedReady for checkin

comment:5 by Mariusz Felisiak <felisiak.mariusz@…>, 4 years ago

Resolution: fixed
Status: assignedclosed

In 2a76f43:

Fixed #32269 -- Fixed parse_duration() for negative days in ISO 8601 format.

Note: See TracTickets for help on using tickets.
Back to Top