diff --git a/couchdb/mapping.py b/couchdb/mapping.py index ef90d2db..626aaedc 100644 --- a/couchdb/mapping.py +++ b/couchdb/mapping.py @@ -474,12 +474,16 @@ def _to_json(self, value): class DateTimeField(Field): """Mapping field for storing date/time values. - + >>> field = DateTimeField() >>> field._to_python('2007-04-01T15:30:00Z') datetime.datetime(2007, 4, 1, 15, 30) - >>> field._to_json(datetime(2007, 4, 1, 15, 30, 0, 9876)) + >>> field._to_python('2007-04-01T15:30:00.009876Z') + datetime.datetime(2007, 4, 1, 15, 30, 0, 9876) + >>> field._to_json(datetime(2007, 4, 1, 15, 30, 0)) '2007-04-01T15:30:00Z' + >>> field._to_json(datetime(2007, 4, 1, 15, 30, 0, 9876)) + '2007-04-01T15:30:00.009876Z' >>> field._to_json(date(2007, 4, 1)) '2007-04-01T00:00:00Z' """ @@ -487,9 +491,15 @@ class DateTimeField(Field): def _to_python(self, value): if isinstance(value, util.strbase): try: - value = value.split('.', 1)[0] # strip out microseconds - value = value.rstrip('Z') # remove timezone separator - value = datetime(*strptime(value, '%Y-%m-%dT%H:%M:%S')[:6]) + split_value = value.split('.') # strip out microseconds + if len(split_value) == 1: # No microseconds provided + value = split_value[0] + value = value.rstrip('Z') #remove timezone separator + value = datetime.strptime(value, '%Y-%m-%dT%H:%M:%S') + else: + value = value.rstrip('Z') + value = datetime.strptime(value, '%Y-%m-%dT%H:%M:%S.%f') + except ValueError: raise ValueError('Invalid ISO date/time %r' % value) return value @@ -499,12 +509,12 @@ def _to_json(self, value): value = datetime.utcfromtimestamp(timegm(value)) elif not isinstance(value, datetime): value = datetime.combine(value, time(0)) - return value.replace(microsecond=0).isoformat() + 'Z' + return value.isoformat() + 'Z' class TimeField(Field): """Mapping field for storing times. - + >>> field = TimeField() >>> field._to_python('15:30:00') datetime.time(15, 30) diff --git a/couchdb/tests/mapping.py b/couchdb/tests/mapping.py index b42ab097..7f49b690 100644 --- a/couchdb/tests/mapping.py +++ b/couchdb/tests/mapping.py @@ -11,6 +11,7 @@ from couchdb import design, mapping from couchdb.tests import testutil +from datetime import datetime class DocumentTestCase(testutil.TempDatabaseMixin, unittest.TestCase): @@ -83,6 +84,15 @@ def test_old_datetime(self): dt = mapping.DateTimeField() assert dt._to_python('1880-01-01T00:00:00Z') + def test_datetime_with_microseconds(self): + dt = mapping.DateTimeField() + assert dt._to_python('2016-06-09T21:21:49.739248Z') + + def test_datetime_to_json(self): + dt = mapping.DateTimeField() + d = datetime.now() + assert dt._to_json(d) + def test_get_has_default(self): doc = mapping.Document() doc.get('foo')