Allow the DateTime type to deserialize YYYY-MM-DD representations.

This commit is contained in:
Chris McDonough
2010-03-30 22:47:02 +00:00
parent e8a80a51e5
commit a1731bc86d
2 changed files with 20 additions and 11 deletions

View File

@@ -603,9 +603,10 @@ class DateTime(object):
the time, and uses the ``default_tzinfo`` to give the the time, and uses the ``default_tzinfo`` to give the
serialization a timezone. serialization a timezone.
This type can only convert ISO8601 values that include a date, a Likewise, for convenience, during deserialization, this type will
time, and a timezone (or ``Z``) in their representations. It will convert ``YYYY-MM-DD`` ISO8601 values to a datetime object. It
fail to parse date-only ISO8601 representations. does so by using midnight of the day as the time, and uses the
``default_tzinfo`` to give the serialization a timezone.
The subnodes of the :class:`colander.SchemaNode` that wraps The subnodes of the :class:`colander.SchemaNode` that wraps
this type are ignored. this type are ignored.
@@ -628,9 +629,14 @@ class DateTime(object):
try: try:
result = iso8601.parse_date(value) result = iso8601.parse_date(value)
except (iso8601.ParseError, TypeError), e: except (iso8601.ParseError, TypeError), e:
raise Invalid(node, try:
'%s cannot be parsed as an iso8601 datetime: %s' % year, month, day = map(int, value.split('-', 2))
(value, e)) result = datetime.datetime(year, month, day,
tzinfo=self.default_tzinfo)
except Exception, e:
raise Invalid(node,
'%s cannot be parsed as an iso8601 date: %s' %
(value, e))
return result return result
class Date(object): class Date(object):

View File

@@ -952,21 +952,24 @@ class TestDateTime(unittest.TestCase):
expected = dt.isoformat() expected = dt.isoformat()
self.assertEqual(result, expected) self.assertEqual(result, expected)
def test_deserialize_invalid_TypeError(self): def test_deserialize_date(self):
import datetime import datetime
# cant parse dates without times import iso8601
date = datetime.date.today() date = datetime.date.today()
typ = self._makeOne() typ = self._makeOne()
formatted = date.isoformat() formatted = date.isoformat()
node = DummySchemaNode(None) node = DummySchemaNode(None)
e = invalid_exc(typ.deserialize, node, formatted) result = typ.deserialize(node, formatted)
self.failUnless('cannot be parsed' in e.msg) expected = datetime.datetime.combine(result, datetime.time())
tzinfo = iso8601.iso8601.Utc()
expected = expected.replace(tzinfo=tzinfo)
self.assertEqual(result.isoformat(), expected.isoformat())
def test_deserialize_invalid_ParseError(self): def test_deserialize_invalid_ParseError(self):
node = DummySchemaNode(None) node = DummySchemaNode(None)
typ = self._makeOne() typ = self._makeOne()
e = invalid_exc(typ.deserialize, node, 'garbage') e = invalid_exc(typ.deserialize, node, 'garbage')
self.failUnless('Unable to parse' in e.msg) self.failUnless('cannot be parsed' in e.msg)
def test_deserialize_success(self): def test_deserialize_success(self):
import datetime import datetime