diff --git a/colander/__init__.py b/colander/__init__.py index e128e86..893f28b 100644 --- a/colander/__init__.py +++ b/colander/__init__.py @@ -603,9 +603,10 @@ class DateTime(object): the time, and uses the ``default_tzinfo`` to give the serialization a timezone. - This type can only convert ISO8601 values that include a date, a - time, and a timezone (or ``Z``) in their representations. It will - fail to parse date-only ISO8601 representations. + Likewise, for convenience, during deserialization, this type will + convert ``YYYY-MM-DD`` ISO8601 values to a datetime object. It + 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 this type are ignored. @@ -628,9 +629,14 @@ class DateTime(object): try: result = iso8601.parse_date(value) except (iso8601.ParseError, TypeError), e: - raise Invalid(node, - '%s cannot be parsed as an iso8601 datetime: %s' % - (value, e)) + try: + year, month, day = map(int, value.split('-', 2)) + 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 class Date(object): diff --git a/colander/tests.py b/colander/tests.py index 3255698..319a7f2 100644 --- a/colander/tests.py +++ b/colander/tests.py @@ -952,21 +952,24 @@ class TestDateTime(unittest.TestCase): expected = dt.isoformat() self.assertEqual(result, expected) - def test_deserialize_invalid_TypeError(self): + def test_deserialize_date(self): import datetime - # cant parse dates without times + import iso8601 date = datetime.date.today() typ = self._makeOne() formatted = date.isoformat() node = DummySchemaNode(None) - e = invalid_exc(typ.deserialize, node, formatted) - self.failUnless('cannot be parsed' in e.msg) + result = typ.deserialize(node, formatted) + 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): node = DummySchemaNode(None) typ = self._makeOne() 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): import datetime