Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Changed timestamp and time typecasting to preserve microseconds. Adde…

…d unit tests to test this behavior, and added a db_typecast unit test module. Refs #306.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@487 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 8d8da826dbf1a702f8b11c3942bf8134c4f0f165 1 parent 8ebe5db
Adrian Holovaty adrianholovaty authored
7 django/core/db/typecasts.py
View
@@ -5,7 +5,7 @@
###############################################
def typecast_date(s):
- return s and datetime.date(*map(int, s.split('-'))) # returns None if s is null
+ return s and datetime.date(*map(int, s.split('-'))) or None # returns None if s is null
def typecast_time(s): # does NOT store time zone information
if not s: return None
@@ -14,7 +14,7 @@ def typecast_time(s): # does NOT store time zone information
seconds, microseconds = seconds.split('.')
else:
microseconds = '0'
- return datetime.time(int(hour), int(minutes), int(seconds), int(microseconds))
+ return datetime.time(int(hour), int(minutes), int(seconds), int(float('.'+microseconds) * 1000000))
def typecast_timestamp(s): # does NOT store time zone information
# "2005-07-29 15:48:00.590358-05"
@@ -39,10 +39,11 @@ def typecast_timestamp(s): # does NOT store time zone information
else:
microseconds = '0'
return datetime.datetime(int(dates[0]), int(dates[1]), int(dates[2]),
- int(times[0]), int(times[1]), int(seconds), int(microseconds))
+ int(times[0]), int(times[1]), int(seconds), int(float('.'+microseconds) * 1000000))
def typecast_boolean(s):
if s is None: return None
+ if not s: return False
return str(s)[0].lower() == 't'
###############################################
4 django/core/meta/fields.py
View
@@ -299,7 +299,7 @@ class DateTimeField(DateField):
def get_db_prep_save(self, value):
# Casts dates into string format for entry into database.
if value is not None:
- value = value.strftime('%Y-%m-%d %H:%M:%S')
+ value = str(value)
return Field.get_db_prep_save(self, value)
def get_manipulator_field_objs(self):
@@ -493,7 +493,7 @@ def pre_save(self, value, add):
def get_db_prep_save(self, value):
# Casts dates into string format for entry into database.
if value is not None:
- value = value.strftime('%H:%M:%S')
+ value = str(value)
return Field.get_db_prep_save(self, value)
def get_manipulator_field_objs(self):
51 tests/othertests/db_typecasts.py
View
@@ -0,0 +1,51 @@
+# Unit tests for django.core.db.typecasts
+
+from django.core.db import typecasts
+import datetime
+
+TEST_CASES = {
+ 'typecast_date': (
+ ('', None),
+ (None, None),
+ ('2005-08-11', datetime.date(2005, 8, 11)),
+ ('1990-01-01', datetime.date(1990, 1, 1)),
+ ),
+ 'typecast_time': (
+ ('', None),
+ (None, None),
+ ('0:00:00', datetime.time(0, 0)),
+ ('0:30:00', datetime.time(0, 30)),
+ ('8:50:00', datetime.time(8, 50)),
+ ('08:50:00', datetime.time(8, 50)),
+ ('12:00:00', datetime.time(12, 00)),
+ ('12:30:00', datetime.time(12, 30)),
+ ('13:00:00', datetime.time(13, 00)),
+ ('23:59:00', datetime.time(23, 59)),
+ ('00:00:12', datetime.time(0, 0, 12)),
+ ('00:00:12.5', datetime.time(0, 0, 12, 500000)),
+ ('7:22:13.312', datetime.time(7, 22, 13, 312000)),
+ ),
+ 'typecast_timestamp': (
+ ('', None),
+ (None, None),
+ ('2005-08-11 0:00:00', datetime.datetime(2005, 8, 11)),
+ ('2005-08-11 0:30:00', datetime.datetime(2005, 8, 11, 0, 30)),
+ ('2005-08-11 8:50:30', datetime.datetime(2005, 8, 11, 8, 50, 30)),
+ ('2005-08-11 8:50:30.123', datetime.datetime(2005, 8, 11, 8, 50, 30, 123000)),
+ ('2005-08-11 8:50:30.9', datetime.datetime(2005, 8, 11, 8, 50, 30, 900000)),
+ ('2005-08-11 8:50:30.312-05', datetime.datetime(2005, 8, 11, 8, 50, 30, 312000)),
+ ('2005-08-11 8:50:30.312+02', datetime.datetime(2005, 8, 11, 8, 50, 30, 312000)),
+ ),
+ 'typecast_boolean': (
+ (None, None),
+ ('', False),
+ ('t', True),
+ ('f', False),
+ ('x', False),
+ ),
+}
+
+for k, v in TEST_CASES.items():
+ for inpt, expected in v:
+ got = getattr(typecasts, k)(inpt)
+ assert got == expected, "In %s: %r doesn't match %r. Got %r instead." % (k, inpt, expected, got)
35 tests/testapp/models/basic.py
View
@@ -120,4 +120,39 @@ class Article(meta.Model):
>>> a6.save()
>>> a6.headline
'Default headline'
+
+# For DateTimeFields, Django saves as much precision (in seconds) as you
+# give it.
+>>> a7 = articles.Article(headline='Article 7', pub_date=datetime(2005, 7, 31, 12, 30))
+>>> a7.save()
+>>> articles.get_object(id__exact=7).pub_date
+datetime.datetime(2005, 7, 31, 12, 30)
+
+>>> a8 = articles.Article(headline='Article 8', pub_date=datetime(2005, 7, 31, 12, 30, 45))
+>>> a8.save()
+>>> articles.get_object(id__exact=8).pub_date
+datetime.datetime(2005, 7, 31, 12, 30, 45)
+"""
+
+from django.conf import settings
+
+building_docs = getattr(settings, 'BUILDING_DOCS', False)
+
+if building_docs or settings.DATABASE_ENGINE == 'postgresql':
+ API_TESTS += """
+# In PostgreSQL, microsecond-level precision is available.
+>>> a9 = articles.Article(headline='Article 9', pub_date=datetime(2005, 7, 31, 12, 30, 45, 180))
+>>> a9.save()
+>>> articles.get_object(id__exact=9).pub_date
+datetime.datetime(2005, 7, 31, 12, 30, 45, 180)
+"""
+
+if building_docs or settings.DATABASE_ENGINE == 'mysql':
+ API_TESTS += """
+# In MySQL, microsecond-level precision isn't available. You'll lose
+# microsecond-level precision once the data is saved.
+>>> a9 = articles.Article(headline='Article 9', pub_date=datetime(2005, 7, 31, 12, 30, 45, 180))
+>>> a9.save()
+>>> articles.get_object(id__exact=9).pub_date
+datetime.datetime(2005, 7, 31, 12, 30, 45)
"""
Please sign in to comment.
Something went wrong with that request. Please try again.