Opened 12 years ago

Closed 12 years ago

#18728 closed Bug (fixed)

dateparse datetime regex should accept colon in TZ offset

Reported by: thaxter Owned by: Aymeric Augustin
Component: Core (Other) Version: 1.4
Severity: Normal Keywords: datetime dateparse iso8601
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

A legitimate ISO8601 datetime such as 2012-08-07T15:17:59.000+0000 will be rejected as input to a DateTime field. The dateparse.datetime_re matches with the colon: 2012-08-07T15:17:59.000+00:00.

According to spec, both are acceptable. Simply adding a ? after the colon in the regex fixes it:

datetime_re = re.compile(
    r'(?P<year>\d{4})-(?P<month>\d{1,2})-(?P<day>\d{1,2})'
    r'[T ](?P<hour>\d{1,2}):(?P<minute>\d{1,2})'
    r'(?::(?P<second>\d{1,2})(?:\.(?P<microsecond>\d{1,6})\d{0,6})?)?'
    r'(?P<tzinfo>Z|[+-]\d{1,2}:?\d{1,2})?$'
)

Diff format:

21c21
<     r'(?P<tzinfo>Z|[+-]\d{1,2}:\d{1,2})?$'
---
>     r'(?P<tzinfo>Z|[+-]\d{1,2}:?\d{1,2})?$'

Attachments (1)

django-dateparse.patch (916 bytes ) - added by jason@… 12 years ago.
patch file for this issue, also found at github thaxter/django

Download all attachments as: .zip

Change History (6)

comment:1 by Aymeric Augustin, 12 years ago

Owner: changed from nobody to Aymeric Augustin

comment:2 by thaxter, 12 years ago

Easy pickings: set

The patch needs an enhancement. When tzinfo is converted to an offset, it uses string subscripting to a string that is now variable/different length. This patch removes the colon and changes the subscript in addition to updating the regex. This prevents a bug that would occur when the minutes in the offset are not zero.

21c21
<     r'(?P<tzinfo>Z|[+-]\d{1,2}:\d{1,2})?$'
---
>     r'(?P<tzinfo>Z|[+-]\d{1,2}:?\d{1,2})?$'
79c79,80
<             offset = 60 * int(tzinfo[1:3]) + int(tzinfo[4:6])
---
>             tzinfo = re.sub(r':','',tzinfo)
>             offset = 60 * int(tzinfo[1:3]) + int(tzinfo[3:5])

This demo code shows that it works.

from django.utils.dateparse import parse_datetime

foo = '2012-08-06T01:00:00+01:02'
bar = '2012-08-06T01:00:00+0102'

print parse_datetime(foo).isoformat()
print parse_datetime(bar).isoformat()


Output:

2012-08-06T01:00:00+01:02
2012-08-06T01:00:00+01:02

by jason@…, 12 years ago

Attachment: django-dateparse.patch added

patch file for this issue, also found at github thaxter/django

comment:3 by Aymeric Augustin, 12 years ago

How is Django supposed to interpret "+123" -- which matches the regexp with your change?

comment:4 by Aymeric Augustin, 12 years ago

Component: UncategorizedCore (Other)
Easy pickings: unset
Triage Stage: UnreviewedAccepted
Type: UncategorizedBug

That said, the current function won't work if the hours and minutes in the offset aren't specified with 2 digits each, and that's a problem we have to fix one way or another.

The two issues are tightly related.

comment:5 by Aymeric Augustin <aymeric.augustin@…>, 12 years ago

Resolution: fixed
Status: newclosed

In [2f59e94a4150c84c8b4e387fd82f0509eadc4f4b]:

Fixed #18728 -- Made colon optional in tzinfo

Made two-digit hours and minutes mandatory in tzinfo (the code used
to crash if a one-digit representation was provided).

Added standalone tests for django.utils.dateparse.

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