Opened 5 years ago
Closed 5 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 , 5 years ago
| Triage Stage: | Unreviewed → Accepted |
|---|
comment:3 by , 5 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
comment:4 by , 5 years ago
| Has patch: | set |
|---|---|
| Owner: | changed from to |
| Triage Stage: | Accepted → Ready for checkin |
Great catch. Would you like to prepare a patch?