Commit 6bfff663 authored by Evan Simpson's avatar Evan Simpson

Mostly fixed Collector #1129. Badly formed ISO8601 dates are rejected,

except that 'Z' is still allowed in front of a '+/-HH:MM' timezone.  I
left that in since it was used elsewhere in the code, and was probably
harmless, whereas the other parse problems caused dates like "2003-2-5"
to be accepted as valid and silently converted into "2003-01-01".

Also re-exposed the DateTime-specific exceptions as attributes of the
DateTime class.  During their recent converted from strings to classes,
they were removed.
parent 608c08b1
......@@ -34,6 +34,8 @@ Zope Changes
Bugs fixed
- Collector #1129: Improper parsing of ISO8601 in DateTime.
- Removed pervasive use of string exceptions (some may still be
hiding in the woodwork, but all raise's with string literals are
gone).
......
......@@ -12,7 +12,7 @@
##############################################################################
"""Encapsulation of date/time values"""
__version__='$Revision: 1.91 $'[11:-2]
__version__='$Revision: 1.92 $'[11:-2]
import os, re, math, DateTimeZone
......@@ -497,6 +497,12 @@ class DateTime:
then the current date/time is returned, represented in the
timezone of the local machine.
# Make class-specific exceptions available as attributes.
DateError = DateError
TimeError = TimeError
DateTimeError = DateTimeError
SyntaxError = SyntaxError
- If the function is invoked with a single string argument
which is a recognized timezone name, an object representing
the current time is returned, represented in the specified
......@@ -1657,7 +1663,8 @@ class DateTime:
hour=minute=seconds=hour_off=min_off=0
datereg = re.compile('([0-9]{4})(-([0-9][0-9]))?(-([0-9][0-9]))?')
timereg = re.compile('([0-9]{2})(:([0-9][0-9]))?(:([0-9][0-9]))?(\.[0-9]{1,20})?')
timereg = re.compile('T([0-9]{2})(:([0-9][0-9]))?(:([0-9][0-9]))?(\.[0-9]{1,20})?')
zonereg = re.compile('([+-][0-9][0-9])(:([0-9][0-9]))')
# Date part
......@@ -1666,21 +1673,33 @@ class DateTime:
if fields[1]: year = int(fields[1])
if fields[3]: month = int(fields[3])
if fields[5]: day = int(fields[5])
t = fields[6]
if t:
if not fields[5]:
# Specifying time requires specifying a day.
raise IndexError
if s.find('T')>-1:
fields = timereg.split(s[s.find('T')+1:])
fields = timereg.split(t)
if fields[1]: hour = int(fields[1])
if fields[3]: minute = int(fields[3])
if fields[5]: seconds = int(fields[5])
if fields[6]: seconds = seconds+float(fields[6])
if s.find('Z')>-1:
pass
if s[-3]==':' and s[-6] in ['+','-']:
hour_off = int(s[-6:-3])
min_off = int(s[-2:])
z = fields[7]
if z and z.startswith('Z'):
# Waaaa! This is wrong, since 'Z' and '+HH:MM'
# are supposed to be mutually exclusive.
# It's only here to prevent breaking 2.7 beta.
z = z[1:]
if z:
fields = zonereg.split(z)
hour_off = int(fields[1])
min_off = int(fields[3])
if fields[4]:
# Garbage after time zone
raise IndexError
return year,month,day,hour,minute,seconds,'GMT%+03d%02d' % (hour_off,min_off)
......
......@@ -257,9 +257,17 @@ class DateTimeTests(unittest.TestCase):
isoDt = DateTime('2002-05-02T08:00:00Z')
self.assertEqual( ref0, isoDt)
isoDt = DateTime('2002-05-02T08:00:00Z-04:00')
isoDt = DateTime('2002-05-02T08:00:00-04:00')
self.assertEqual( ref1, isoDt)
dgood = '2002-05-02'
tgood = 'T08:00:00-04:00'
for dbad in '2002-5-2', '2002-10-2', '2002-2-10', '02-2-10':
self.assertRaises(DateTime.SyntaxError, DateTime, dbad)
self.assertRaises(DateTime.SyntaxError, DateTime, dbad + tgood)
for tbad in '08:00', 'T8:00': #, 'T08:00Z-04:00':
self.assertRaises(DateTime.SyntaxError, DateTime, dgood + tbad)
def testJulianWeek(self):
""" check JulianDayWeek function """
......@@ -279,13 +287,13 @@ class DateTimeTests(unittest.TestCase):
def testRFC822(self):
'''rfc822 conversion'''
dt = DateTime('2002-05-02T08:00:00Z+00:00')
dt = DateTime('2002-05-02T08:00:00+00:00')
self.assertEqual(dt.rfc822(), 'Thu, 02 May 2002 08:00:00 +0000')
dt = DateTime('2002-05-02T08:00:00Z+02:00')
dt = DateTime('2002-05-02T08:00:00+02:00')
self.assertEqual(dt.rfc822(), 'Thu, 02 May 2002 08:00:00 +0200')
dt = DateTime('2002-05-02T08:00:00Z-02:00')
dt = DateTime('2002-05-02T08:00:00-02:00')
self.assertEqual(dt.rfc822(), 'Thu, 02 May 2002 08:00:00 -0200')
# Checking that conversion from local time is working.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment