Removed DatabaseFeatures.supports_microsecond_precision.
MySQL 5.5 (refs #28552) was the last database to use it.
This commit is contained in:
parent
8a1768432b
commit
a80903b711
|
@ -70,9 +70,6 @@ class BaseDatabaseFeatures:
|
|||
# by returning the type used to store duration field?
|
||||
supports_temporal_subtraction = False
|
||||
|
||||
# Do time/datetime fields have microsecond precision?
|
||||
supports_microsecond_precision = True
|
||||
|
||||
# Does the __regex lookup support backreferencing and grouping?
|
||||
supports_regex_backreferencing = True
|
||||
|
||||
|
|
|
@ -6,8 +6,7 @@ from django.db import DEFAULT_DB_ALIAS, DatabaseError, connections
|
|||
from django.db.models.manager import BaseManager
|
||||
from django.db.models.query import EmptyQuerySet, QuerySet
|
||||
from django.test import (
|
||||
SimpleTestCase, TestCase, TransactionTestCase, skipIfDBFeature,
|
||||
skipUnlessDBFeature,
|
||||
SimpleTestCase, TestCase, TransactionTestCase, skipUnlessDBFeature,
|
||||
)
|
||||
from django.utils.translation import gettext_lazy
|
||||
|
||||
|
@ -164,9 +163,7 @@ class ModelTest(TestCase):
|
|||
|
||||
self.assertNotEqual(Article.objects.get(id__exact=a1.id), Article.objects.get(id__exact=a2.id))
|
||||
|
||||
@skipUnlessDBFeature('supports_microsecond_precision')
|
||||
def test_microsecond_precision(self):
|
||||
# In PostgreSQL, microsecond-level precision is available.
|
||||
a9 = Article(
|
||||
headline='Article 9',
|
||||
pub_date=datetime(2005, 7, 31, 12, 30, 45, 180),
|
||||
|
@ -174,33 +171,6 @@ class ModelTest(TestCase):
|
|||
a9.save()
|
||||
self.assertEqual(Article.objects.get(pk=a9.pk).pub_date, datetime(2005, 7, 31, 12, 30, 45, 180))
|
||||
|
||||
@skipIfDBFeature('supports_microsecond_precision')
|
||||
def test_microsecond_precision_not_supported(self):
|
||||
# In MySQL, microsecond-level precision isn't always available. You'll
|
||||
# lose microsecond-level precision once the data is saved.
|
||||
a9 = Article(
|
||||
headline='Article 9',
|
||||
pub_date=datetime(2005, 7, 31, 12, 30, 45, 180),
|
||||
)
|
||||
a9.save()
|
||||
self.assertEqual(
|
||||
Article.objects.get(id__exact=a9.id).pub_date,
|
||||
datetime(2005, 7, 31, 12, 30, 45),
|
||||
)
|
||||
|
||||
@skipIfDBFeature('supports_microsecond_precision')
|
||||
def test_microsecond_precision_not_supported_edge_case(self):
|
||||
# In MySQL, microsecond-level precision isn't always available. You'll
|
||||
# lose microsecond-level precision once the data is saved.
|
||||
a = Article.objects.create(
|
||||
headline='Article',
|
||||
pub_date=datetime(2008, 12, 31, 23, 59, 59, 999999),
|
||||
)
|
||||
self.assertEqual(
|
||||
Article.objects.get(pk=a.pk).pub_date,
|
||||
datetime(2008, 12, 31, 23, 59, 59),
|
||||
)
|
||||
|
||||
def test_manually_specify_primary_key(self):
|
||||
# You can manually specify the primary key when creating a new object.
|
||||
a101 = Article(
|
||||
|
@ -667,14 +637,10 @@ class SelectOnSaveTests(TestCase):
|
|||
|
||||
|
||||
class ModelRefreshTests(TestCase):
|
||||
def _truncate_ms(self, val):
|
||||
# MySQL < 5.6.4 removes microseconds from the datetimes which can cause
|
||||
# problems when comparing the original value to that loaded from DB
|
||||
return val - timedelta(microseconds=val.microsecond)
|
||||
|
||||
def test_refresh(self):
|
||||
a = Article.objects.create(pub_date=self._truncate_ms(datetime.now()))
|
||||
Article.objects.create(pub_date=self._truncate_ms(datetime.now()))
|
||||
a = Article.objects.create(pub_date=datetime.now())
|
||||
Article.objects.create(pub_date=datetime.now())
|
||||
Article.objects.filter(pk=a.pk).update(headline='new headline')
|
||||
with self.assertNumQueries(1):
|
||||
a.refresh_from_db()
|
||||
|
@ -722,7 +688,7 @@ class ModelRefreshTests(TestCase):
|
|||
self.assertEqual(s2.selfref, s1)
|
||||
|
||||
def test_refresh_unsaved(self):
|
||||
pub_date = self._truncate_ms(datetime.now())
|
||||
pub_date = datetime.now()
|
||||
a = Article.objects.create(pub_date=pub_date)
|
||||
a2 = Article(id=a.pk)
|
||||
with self.assertNumQueries(1):
|
||||
|
@ -742,6 +708,6 @@ class ModelRefreshTests(TestCase):
|
|||
self.assertIsNone(s1.article)
|
||||
|
||||
def test_refresh_no_fields(self):
|
||||
a = Article.objects.create(pub_date=self._truncate_ms(datetime.now()))
|
||||
a = Article.objects.create(pub_date=datetime.now())
|
||||
with self.assertNumQueries(0):
|
||||
a.refresh_from_db(fields=[])
|
||||
|
|
|
@ -3,7 +3,6 @@ from datetime import datetime
|
|||
import pytz
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import connection
|
||||
from django.db.models import DateField, DateTimeField, IntegerField, TimeField
|
||||
from django.db.models.functions import (
|
||||
Extract, ExtractDay, ExtractHour, ExtractMinute, ExtractMonth,
|
||||
|
@ -19,10 +18,6 @@ from django.utils import timezone
|
|||
from .models import DTModel
|
||||
|
||||
|
||||
def microsecond_support(value):
|
||||
return value if connection.features.supports_microsecond_precision else value.replace(microsecond=0)
|
||||
|
||||
|
||||
def truncate_to(value, kind, tzinfo=None):
|
||||
# Convert to target timezone before truncation
|
||||
if tzinfo is not None:
|
||||
|
@ -138,8 +133,8 @@ class DateFunctionTests(TestCase):
|
|||
self.assertEqual(str(qs.query).count('extract'), 0)
|
||||
|
||||
def test_extract_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123))
|
||||
start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321)
|
||||
end_datetime = datetime(2016, 6, 15, 14, 10, 50, 123)
|
||||
if settings.USE_TZ:
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
|
@ -212,8 +207,8 @@ class DateFunctionTests(TestCase):
|
|||
|
||||
@skipUnlessDBFeature('has_native_duration_field')
|
||||
def test_extract_duration(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123))
|
||||
start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321)
|
||||
end_datetime = datetime(2016, 6, 15, 14, 10, 50, 123)
|
||||
if settings.USE_TZ:
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
|
@ -241,8 +236,8 @@ class DateFunctionTests(TestCase):
|
|||
list(DTModel.objects.annotate(extracted=Extract('duration', 'second')))
|
||||
|
||||
def test_extract_year_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123))
|
||||
start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321)
|
||||
end_datetime = datetime(2016, 6, 15, 14, 10, 50, 123)
|
||||
if settings.USE_TZ:
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
|
@ -261,8 +256,8 @@ class DateFunctionTests(TestCase):
|
|||
self.assertEqual(DTModel.objects.filter(start_datetime__year=ExtractYear('start_datetime')).count(), 2)
|
||||
|
||||
def test_extract_month_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123))
|
||||
start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321)
|
||||
end_datetime = datetime(2016, 6, 15, 14, 10, 50, 123)
|
||||
if settings.USE_TZ:
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
|
@ -281,8 +276,8 @@ class DateFunctionTests(TestCase):
|
|||
self.assertEqual(DTModel.objects.filter(start_datetime__month=ExtractMonth('start_datetime')).count(), 2)
|
||||
|
||||
def test_extract_day_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123))
|
||||
start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321)
|
||||
end_datetime = datetime(2016, 6, 15, 14, 10, 50, 123)
|
||||
if settings.USE_TZ:
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
|
@ -301,8 +296,8 @@ class DateFunctionTests(TestCase):
|
|||
self.assertEqual(DTModel.objects.filter(start_datetime__day=ExtractDay('start_datetime')).count(), 2)
|
||||
|
||||
def test_extract_week_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123))
|
||||
start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321)
|
||||
end_datetime = datetime(2016, 6, 15, 14, 10, 50, 123)
|
||||
if settings.USE_TZ:
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
|
@ -322,8 +317,8 @@ class DateFunctionTests(TestCase):
|
|||
self.assertEqual(DTModel.objects.filter(start_datetime__week=ExtractWeek('start_datetime')).count(), 2)
|
||||
|
||||
def test_extract_quarter_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = microsecond_support(datetime(2016, 8, 15, 14, 10, 50, 123))
|
||||
start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321)
|
||||
end_datetime = datetime(2016, 8, 15, 14, 10, 50, 123)
|
||||
if settings.USE_TZ:
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
|
@ -342,12 +337,12 @@ class DateFunctionTests(TestCase):
|
|||
self.assertEqual(DTModel.objects.filter(start_datetime__quarter=ExtractQuarter('start_datetime')).count(), 2)
|
||||
|
||||
def test_extract_quarter_func_boundaries(self):
|
||||
end_datetime = microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123))
|
||||
end_datetime = datetime(2016, 6, 15, 14, 10, 50, 123)
|
||||
if settings.USE_TZ:
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
|
||||
last_quarter_2014 = microsecond_support(datetime(2014, 12, 31, 13, 0))
|
||||
first_quarter_2015 = microsecond_support(datetime(2015, 1, 1, 13, 0))
|
||||
last_quarter_2014 = datetime(2014, 12, 31, 13, 0)
|
||||
first_quarter_2015 = datetime(2015, 1, 1, 13, 0)
|
||||
if settings.USE_TZ:
|
||||
last_quarter_2014 = timezone.make_aware(last_quarter_2014, is_dst=False)
|
||||
first_quarter_2015 = timezone.make_aware(first_quarter_2015, is_dst=False)
|
||||
|
@ -363,13 +358,13 @@ class DateFunctionTests(TestCase):
|
|||
], lambda m: (m.start_datetime, m.extracted))
|
||||
|
||||
def test_extract_week_func_boundaries(self):
|
||||
end_datetime = microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123))
|
||||
end_datetime = datetime(2016, 6, 15, 14, 10, 50, 123)
|
||||
if settings.USE_TZ:
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
|
||||
week_52_day_2014 = microsecond_support(datetime(2014, 12, 27, 13, 0)) # Sunday
|
||||
week_1_day_2014_2015 = microsecond_support(datetime(2014, 12, 31, 13, 0)) # Wednesday
|
||||
week_53_day_2015 = microsecond_support(datetime(2015, 12, 31, 13, 0)) # Thursday
|
||||
week_52_day_2014 = datetime(2014, 12, 27, 13, 0) # Sunday
|
||||
week_1_day_2014_2015 = datetime(2014, 12, 31, 13, 0) # Wednesday
|
||||
week_53_day_2015 = datetime(2015, 12, 31, 13, 0) # Thursday
|
||||
if settings.USE_TZ:
|
||||
week_1_day_2014_2015 = timezone.make_aware(week_1_day_2014_2015, is_dst=False)
|
||||
week_52_day_2014 = timezone.make_aware(week_52_day_2014, is_dst=False)
|
||||
|
@ -389,8 +384,8 @@ class DateFunctionTests(TestCase):
|
|||
], lambda m: (m.start_datetime, m.extracted))
|
||||
|
||||
def test_extract_weekday_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123))
|
||||
start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321)
|
||||
end_datetime = datetime(2016, 6, 15, 14, 10, 50, 123)
|
||||
if settings.USE_TZ:
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
|
@ -415,8 +410,8 @@ class DateFunctionTests(TestCase):
|
|||
self.assertEqual(DTModel.objects.filter(start_datetime__week_day=ExtractWeekDay('start_datetime')).count(), 2)
|
||||
|
||||
def test_extract_hour_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123))
|
||||
start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321)
|
||||
end_datetime = datetime(2016, 6, 15, 14, 10, 50, 123)
|
||||
if settings.USE_TZ:
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
|
@ -435,8 +430,8 @@ class DateFunctionTests(TestCase):
|
|||
self.assertEqual(DTModel.objects.filter(start_datetime__hour=ExtractHour('start_datetime')).count(), 2)
|
||||
|
||||
def test_extract_minute_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123))
|
||||
start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321)
|
||||
end_datetime = datetime(2016, 6, 15, 14, 10, 50, 123)
|
||||
if settings.USE_TZ:
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
|
@ -455,8 +450,8 @@ class DateFunctionTests(TestCase):
|
|||
self.assertEqual(DTModel.objects.filter(start_datetime__minute=ExtractMinute('start_datetime')).count(), 2)
|
||||
|
||||
def test_extract_second_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123))
|
||||
start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321)
|
||||
end_datetime = datetime(2016, 6, 15, 14, 10, 50, 123)
|
||||
if settings.USE_TZ:
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
|
@ -475,8 +470,8 @@ class DateFunctionTests(TestCase):
|
|||
self.assertEqual(DTModel.objects.filter(start_datetime__second=ExtractSecond('start_datetime')).count(), 2)
|
||||
|
||||
def test_trunc_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123))
|
||||
start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321)
|
||||
end_datetime = datetime(2016, 6, 15, 14, 10, 50, 123)
|
||||
if settings.USE_TZ:
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
|
@ -557,8 +552,8 @@ class DateFunctionTests(TestCase):
|
|||
self.assertEqual(qs.count(), 2)
|
||||
|
||||
def test_trunc_year_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = truncate_to(microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123)), 'year')
|
||||
start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321)
|
||||
end_datetime = truncate_to(datetime(2016, 6, 15, 14, 10, 50, 123), 'year')
|
||||
if settings.USE_TZ:
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
|
@ -589,10 +584,10 @@ class DateFunctionTests(TestCase):
|
|||
list(DTModel.objects.annotate(truncated=TruncYear('start_time', output_field=TimeField())))
|
||||
|
||||
def test_trunc_quarter_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = truncate_to(microsecond_support(datetime(2016, 10, 15, 14, 10, 50, 123)), 'quarter')
|
||||
last_quarter_2015 = truncate_to(microsecond_support(datetime(2015, 12, 31, 14, 10, 50, 123)), 'quarter')
|
||||
first_quarter_2016 = truncate_to(microsecond_support(datetime(2016, 1, 1, 14, 10, 50, 123)), 'quarter')
|
||||
start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321)
|
||||
end_datetime = truncate_to(datetime(2016, 10, 15, 14, 10, 50, 123), 'quarter')
|
||||
last_quarter_2015 = truncate_to(datetime(2015, 12, 31, 14, 10, 50, 123), 'quarter')
|
||||
first_quarter_2016 = truncate_to(datetime(2016, 1, 1, 14, 10, 50, 123), 'quarter')
|
||||
if settings.USE_TZ:
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
|
@ -630,8 +625,8 @@ class DateFunctionTests(TestCase):
|
|||
list(DTModel.objects.annotate(truncated=TruncQuarter('start_time', output_field=TimeField())))
|
||||
|
||||
def test_trunc_month_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = truncate_to(microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123)), 'month')
|
||||
start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321)
|
||||
end_datetime = truncate_to(datetime(2016, 6, 15, 14, 10, 50, 123), 'month')
|
||||
if settings.USE_TZ:
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
|
@ -662,8 +657,8 @@ class DateFunctionTests(TestCase):
|
|||
list(DTModel.objects.annotate(truncated=TruncMonth('start_time', output_field=TimeField())))
|
||||
|
||||
def test_trunc_date_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123))
|
||||
start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321)
|
||||
end_datetime = datetime(2016, 6, 15, 14, 10, 50, 123)
|
||||
if settings.USE_TZ:
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
|
@ -686,8 +681,8 @@ class DateFunctionTests(TestCase):
|
|||
list(DTModel.objects.annotate(truncated=TruncDate('start_time', output_field=TimeField())))
|
||||
|
||||
def test_trunc_time_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123))
|
||||
start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321)
|
||||
end_datetime = datetime(2016, 6, 15, 14, 10, 50, 123)
|
||||
if settings.USE_TZ:
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
|
@ -710,8 +705,8 @@ class DateFunctionTests(TestCase):
|
|||
list(DTModel.objects.annotate(truncated=TruncTime('start_date', output_field=DateField())))
|
||||
|
||||
def test_trunc_day_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = truncate_to(microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123)), 'day')
|
||||
start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321)
|
||||
end_datetime = truncate_to(datetime(2016, 6, 15, 14, 10, 50, 123), 'day')
|
||||
if settings.USE_TZ:
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
|
@ -734,8 +729,8 @@ class DateFunctionTests(TestCase):
|
|||
list(DTModel.objects.annotate(truncated=TruncDay('start_time', output_field=TimeField())))
|
||||
|
||||
def test_trunc_hour_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = truncate_to(microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123)), 'hour')
|
||||
start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321)
|
||||
end_datetime = truncate_to(datetime(2016, 6, 15, 14, 10, 50, 123), 'hour')
|
||||
if settings.USE_TZ:
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
|
@ -766,8 +761,8 @@ class DateFunctionTests(TestCase):
|
|||
list(DTModel.objects.annotate(truncated=TruncHour('start_date', output_field=DateField())))
|
||||
|
||||
def test_trunc_minute_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = truncate_to(microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123)), 'minute')
|
||||
start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321)
|
||||
end_datetime = truncate_to(datetime(2016, 6, 15, 14, 10, 50, 123), 'minute')
|
||||
if settings.USE_TZ:
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
|
@ -798,8 +793,8 @@ class DateFunctionTests(TestCase):
|
|||
list(DTModel.objects.annotate(truncated=TruncMinute('start_date', output_field=DateField())))
|
||||
|
||||
def test_trunc_second_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = truncate_to(microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123)), 'second')
|
||||
start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321)
|
||||
end_datetime = truncate_to(datetime(2016, 6, 15, 14, 10, 50, 123), 'second')
|
||||
if settings.USE_TZ:
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
|
@ -821,9 +816,7 @@ class DateFunctionTests(TestCase):
|
|||
],
|
||||
lambda m: (m.start_datetime, m.extracted)
|
||||
)
|
||||
|
||||
result = 1 if connection.features.supports_microsecond_precision else 2
|
||||
self.assertEqual(DTModel.objects.filter(start_datetime=TruncSecond('start_datetime')).count(), result)
|
||||
self.assertEqual(DTModel.objects.filter(start_datetime=TruncSecond('start_datetime')).count(), 1)
|
||||
|
||||
with self.assertRaisesMessage(ValueError, "Cannot truncate DateField 'start_date' to DateTimeField"):
|
||||
list(DTModel.objects.annotate(truncated=TruncSecond('start_date')))
|
||||
|
@ -836,8 +829,8 @@ class DateFunctionTests(TestCase):
|
|||
class DateFunctionWithTimeZoneTests(DateFunctionTests):
|
||||
|
||||
def test_extract_func_with_timezone(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 23, 30, 1, 321))
|
||||
end_datetime = microsecond_support(datetime(2015, 6, 16, 13, 11, 27, 123))
|
||||
start_datetime = datetime(2015, 6, 15, 23, 30, 1, 321)
|
||||
end_datetime = datetime(2015, 6, 16, 13, 11, 27, 123)
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
self.create_model(start_datetime, end_datetime)
|
||||
|
@ -877,8 +870,8 @@ class DateFunctionWithTimeZoneTests(DateFunctionTests):
|
|||
self.assertEqual(melb_model.hour_melb, 9)
|
||||
|
||||
def test_extract_func_explicit_timezone_priority(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 23, 30, 1, 321))
|
||||
end_datetime = microsecond_support(datetime(2015, 6, 16, 13, 11, 27, 123))
|
||||
start_datetime = datetime(2015, 6, 15, 23, 30, 1, 321)
|
||||
end_datetime = datetime(2015, 6, 16, 13, 11, 27, 123)
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
self.create_model(start_datetime, end_datetime)
|
||||
|
@ -893,8 +886,8 @@ class DateFunctionWithTimeZoneTests(DateFunctionTests):
|
|||
self.assertEqual(model.day_utc, 15)
|
||||
|
||||
def test_trunc_timezone_applied_before_truncation(self):
|
||||
start_datetime = microsecond_support(datetime(2016, 1, 1, 1, 30, 50, 321))
|
||||
end_datetime = microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123))
|
||||
start_datetime = datetime(2016, 1, 1, 1, 30, 50, 321)
|
||||
end_datetime = datetime(2016, 6, 15, 14, 10, 50, 123)
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
self.create_model(start_datetime, end_datetime)
|
||||
|
@ -919,8 +912,8 @@ class DateFunctionWithTimeZoneTests(DateFunctionTests):
|
|||
If the truncated datetime transitions to a different offset (daylight
|
||||
saving) then the returned value will have that new timezone/offset.
|
||||
"""
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123))
|
||||
start_datetime = datetime(2015, 6, 15, 14, 30, 50, 321)
|
||||
end_datetime = datetime(2016, 6, 15, 14, 10, 50, 123)
|
||||
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
|
||||
end_datetime = timezone.make_aware(end_datetime, is_dst=False)
|
||||
self.create_model(start_datetime, end_datetime)
|
||||
|
|
|
@ -20,10 +20,6 @@ lorem_ipsum = """
|
|||
tempor incididunt ut labore et dolore magna aliqua."""
|
||||
|
||||
|
||||
def truncate_microseconds(value):
|
||||
return value if connection.features.supports_microsecond_precision else value.replace(microsecond=0)
|
||||
|
||||
|
||||
class FunctionTests(TestCase):
|
||||
|
||||
def test_coalesce(self):
|
||||
|
@ -121,7 +117,7 @@ class FunctionTests(TestCase):
|
|||
articles = Article.objects.annotate(
|
||||
last_updated=Greatest('written', 'published'),
|
||||
)
|
||||
self.assertEqual(articles.first().last_updated, truncate_microseconds(now))
|
||||
self.assertEqual(articles.first().last_updated, now)
|
||||
|
||||
@skipUnlessDBFeature('greatest_least_ignores_nulls')
|
||||
def test_greatest_ignores_null(self):
|
||||
|
@ -174,7 +170,7 @@ class FunctionTests(TestCase):
|
|||
Coalesce('published', past_sql),
|
||||
),
|
||||
)
|
||||
self.assertEqual(articles.first().last_updated, truncate_microseconds(now))
|
||||
self.assertEqual(articles.first().last_updated, now)
|
||||
|
||||
def test_greatest_all_null(self):
|
||||
Article.objects.create(title="Testing with Django", written=timezone.now())
|
||||
|
@ -225,7 +221,7 @@ class FunctionTests(TestCase):
|
|||
articles = Article.objects.annotate(
|
||||
first_updated=Least('written', 'published'),
|
||||
)
|
||||
self.assertEqual(articles.first().first_updated, truncate_microseconds(before))
|
||||
self.assertEqual(articles.first().first_updated, before)
|
||||
|
||||
@skipUnlessDBFeature('greatest_least_ignores_nulls')
|
||||
def test_least_ignores_null(self):
|
||||
|
@ -278,7 +274,7 @@ class FunctionTests(TestCase):
|
|||
Coalesce('published', future_sql),
|
||||
),
|
||||
)
|
||||
self.assertEqual(articles.first().last_updated, truncate_microseconds(now))
|
||||
self.assertEqual(articles.first().last_updated, now)
|
||||
|
||||
def test_least_all_null(self):
|
||||
Article.objects.create(title="Testing with Django", written=timezone.now())
|
||||
|
|
|
@ -1028,19 +1028,16 @@ class FTimeDeltaTests(TestCase):
|
|||
|
||||
# e1: started one day after assigned, tiny duration, data
|
||||
# set so that end time has no fractional seconds, which
|
||||
# tests an edge case on sqlite. This Experiment is only
|
||||
# included in the test data when the DB supports microsecond
|
||||
# precision.
|
||||
if connection.features.supports_microsecond_precision:
|
||||
delay = datetime.timedelta(1)
|
||||
end = stime + delay + delta1
|
||||
e1 = Experiment.objects.create(
|
||||
name='e1', assigned=sday, start=stime + delay, end=end,
|
||||
completed=end.date(), estimated_time=delta1,
|
||||
)
|
||||
cls.deltas.append(delta1)
|
||||
cls.delays.append(e1.start - datetime.datetime.combine(e1.assigned, midnight))
|
||||
cls.days_long.append(e1.completed - e1.assigned)
|
||||
# tests an edge case on sqlite.
|
||||
delay = datetime.timedelta(1)
|
||||
end = stime + delay + delta1
|
||||
e1 = Experiment.objects.create(
|
||||
name='e1', assigned=sday, start=stime + delay, end=end,
|
||||
completed=end.date(), estimated_time=delta1,
|
||||
)
|
||||
cls.deltas.append(delta1)
|
||||
cls.delays.append(e1.start - datetime.datetime.combine(e1.assigned, midnight))
|
||||
cls.days_long.append(e1.completed - e1.assigned)
|
||||
|
||||
# e2: started three days after assigned, small duration
|
||||
end = stime + delta2
|
||||
|
@ -1144,8 +1141,6 @@ class FTimeDeltaTests(TestCase):
|
|||
def test_mixed_comparisons1(self):
|
||||
for i in range(len(self.delays)):
|
||||
delay = self.delays[i]
|
||||
if not connection.features.supports_microsecond_precision:
|
||||
delay = datetime.timedelta(delay.days, delay.seconds)
|
||||
test_set = [e.name for e in Experiment.objects.filter(assigned__gt=F('start') - delay)]
|
||||
self.assertEqual(test_set, self.expnames[:i])
|
||||
|
||||
|
@ -1213,27 +1208,21 @@ class FTimeDeltaTests(TestCase):
|
|||
self.assertEqual(at_least_120_days, {'e5'})
|
||||
|
||||
less_than_5_days = {e.name for e in queryset.filter(completion_duration__lt=datetime.timedelta(days=5))}
|
||||
expected = {'e0', 'e2'}
|
||||
if connection.features.supports_microsecond_precision:
|
||||
expected.add('e1')
|
||||
self.assertEqual(less_than_5_days, expected)
|
||||
self.assertEqual(less_than_5_days, {'e0', 'e1', 'e2'})
|
||||
|
||||
@skipUnlessDBFeature('supports_temporal_subtraction')
|
||||
def test_time_subtraction(self):
|
||||
if connection.features.supports_microsecond_precision:
|
||||
time = datetime.time(12, 30, 15, 2345)
|
||||
timedelta = datetime.timedelta(hours=1, minutes=15, seconds=15, microseconds=2345)
|
||||
else:
|
||||
time = datetime.time(12, 30, 15)
|
||||
timedelta = datetime.timedelta(hours=1, minutes=15, seconds=15)
|
||||
Time.objects.create(time=time)
|
||||
Time.objects.create(time=datetime.time(12, 30, 15, 2345))
|
||||
queryset = Time.objects.annotate(
|
||||
difference=ExpressionWrapper(
|
||||
F('time') - Value(datetime.time(11, 15, 0), output_field=models.TimeField()),
|
||||
output_field=models.DurationField(),
|
||||
)
|
||||
)
|
||||
self.assertEqual(queryset.get().difference, timedelta)
|
||||
self.assertEqual(
|
||||
queryset.get().difference,
|
||||
datetime.timedelta(hours=1, minutes=15, seconds=15, microseconds=2345)
|
||||
)
|
||||
|
||||
@skipUnlessDBFeature('supports_temporal_subtraction')
|
||||
def test_datetime_subtraction(self):
|
||||
|
@ -1274,10 +1263,9 @@ class FTimeDeltaTests(TestCase):
|
|||
new_start=F('start_sub_hours') + datetime.timedelta(days=-2),
|
||||
)
|
||||
expected_start = datetime.datetime(2010, 6, 23, 9, 45, 0)
|
||||
if connection.features.supports_microsecond_precision:
|
||||
# subtract 30 microseconds
|
||||
experiments = experiments.annotate(new_start=F('new_start') + datetime.timedelta(microseconds=-30))
|
||||
expected_start += datetime.timedelta(microseconds=+746970)
|
||||
# subtract 30 microseconds
|
||||
experiments = experiments.annotate(new_start=F('new_start') + datetime.timedelta(microseconds=-30))
|
||||
expected_start += datetime.timedelta(microseconds=+746970)
|
||||
experiments.update(start=F('new_start'))
|
||||
e0 = Experiment.objects.get(name='e0')
|
||||
self.assertEqual(e0.start, expected_start)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from datetime import datetime
|
||||
from operator import attrgetter
|
||||
|
||||
from django.test import TestCase, skipUnlessDBFeature
|
||||
from django.test import TestCase
|
||||
|
||||
from .models import (
|
||||
CustomMembership, Employee, Event, Friendship, Group, Ingredient,
|
||||
|
@ -196,7 +196,6 @@ class M2mThroughTests(TestCase):
|
|||
attrgetter("name")
|
||||
)
|
||||
|
||||
@skipUnlessDBFeature('supports_microsecond_precision')
|
||||
def test_order_by_relational_field_through_model(self):
|
||||
CustomMembership.objects.create(person=self.jim, group=self.rock)
|
||||
CustomMembership.objects.create(person=self.bob, group=self.rock)
|
||||
|
|
|
@ -24,7 +24,6 @@ class DateTimeFieldTests(TestCase):
|
|||
self.assertEqual(f.to_python('01:02:03.000004'), datetime.time(1, 2, 3, 4))
|
||||
self.assertEqual(f.to_python('01:02:03.999999'), datetime.time(1, 2, 3, 999999))
|
||||
|
||||
@skipUnlessDBFeature('supports_microsecond_precision')
|
||||
def test_datetimes_save_completely(self):
|
||||
dat = datetime.date(2014, 3, 12)
|
||||
datetim = datetime.datetime(2014, 3, 12, 21, 22, 23, 240000)
|
||||
|
|
|
@ -56,21 +56,12 @@ class LegacyDatabaseTests(TestCase):
|
|||
event = Event.objects.get()
|
||||
self.assertEqual(event.dt, dt)
|
||||
|
||||
@skipUnlessDBFeature('supports_microsecond_precision')
|
||||
def test_naive_datetime_with_microsecond(self):
|
||||
dt = datetime.datetime(2011, 9, 1, 13, 20, 30, 405060)
|
||||
Event.objects.create(dt=dt)
|
||||
event = Event.objects.get()
|
||||
self.assertEqual(event.dt, dt)
|
||||
|
||||
@skipIfDBFeature('supports_microsecond_precision')
|
||||
def test_naive_datetime_with_microsecond_unsupported(self):
|
||||
dt = datetime.datetime(2011, 9, 1, 13, 20, 30, 405060)
|
||||
Event.objects.create(dt=dt)
|
||||
event = Event.objects.get()
|
||||
# microseconds are lost during a round-trip in the database
|
||||
self.assertEqual(event.dt, dt.replace(microsecond=0))
|
||||
|
||||
@skipUnlessDBFeature('supports_timezones')
|
||||
def test_aware_datetime_in_local_timezone(self):
|
||||
dt = datetime.datetime(2011, 9, 1, 13, 20, 30, tzinfo=EAT)
|
||||
|
@ -81,7 +72,6 @@ class LegacyDatabaseTests(TestCase):
|
|||
self.assertEqual(event.dt.replace(tzinfo=EAT), dt)
|
||||
|
||||
@skipUnlessDBFeature('supports_timezones')
|
||||
@skipUnlessDBFeature('supports_microsecond_precision')
|
||||
def test_aware_datetime_in_local_timezone_with_microsecond(self):
|
||||
dt = datetime.datetime(2011, 9, 1, 13, 20, 30, 405060, tzinfo=EAT)
|
||||
Event.objects.create(dt=dt)
|
||||
|
@ -90,18 +80,6 @@ class LegacyDatabaseTests(TestCase):
|
|||
# interpret the naive datetime in local time to get the correct value
|
||||
self.assertEqual(event.dt.replace(tzinfo=EAT), dt)
|
||||
|
||||
# This combination actually never happens.
|
||||
@skipUnlessDBFeature('supports_timezones')
|
||||
@skipIfDBFeature('supports_microsecond_precision')
|
||||
def test_aware_datetime_in_local_timezone_with_microsecond_unsupported(self):
|
||||
dt = datetime.datetime(2011, 9, 1, 13, 20, 30, 405060, tzinfo=EAT)
|
||||
Event.objects.create(dt=dt)
|
||||
event = Event.objects.get()
|
||||
self.assertIsNone(event.dt.tzinfo)
|
||||
# interpret the naive datetime in local time to get the correct value
|
||||
# microseconds are lost during a round-trip in the database
|
||||
self.assertEqual(event.dt.replace(tzinfo=EAT), dt.replace(microsecond=0))
|
||||
|
||||
@skipUnlessDBFeature('supports_timezones')
|
||||
def test_aware_datetime_in_utc(self):
|
||||
dt = datetime.datetime(2011, 9, 1, 10, 20, 30, tzinfo=UTC)
|
||||
|
@ -274,7 +252,6 @@ class NewDatabaseTests(TestCase):
|
|||
self.assertEqual(event.dt, datetime.datetime(2011, 9, 1, tzinfo=EAT))
|
||||
|
||||
@requires_tz_support
|
||||
@skipUnlessDBFeature('supports_microsecond_precision')
|
||||
def test_naive_datetime_with_microsecond(self):
|
||||
dt = datetime.datetime(2011, 9, 1, 13, 20, 30, 405060)
|
||||
with warnings.catch_warnings(record=True) as recorded:
|
||||
|
@ -288,43 +265,18 @@ class NewDatabaseTests(TestCase):
|
|||
# naive datetimes are interpreted in local time
|
||||
self.assertEqual(event.dt, dt.replace(tzinfo=EAT))
|
||||
|
||||
@requires_tz_support
|
||||
@skipIfDBFeature('supports_microsecond_precision')
|
||||
def test_naive_datetime_with_microsecond_unsupported(self):
|
||||
dt = datetime.datetime(2011, 9, 1, 13, 20, 30, 405060)
|
||||
with warnings.catch_warnings(record=True) as recorded:
|
||||
warnings.simplefilter('always')
|
||||
Event.objects.create(dt=dt)
|
||||
self.assertEqual(len(recorded), 1)
|
||||
msg = str(recorded[0].message)
|
||||
self.assertTrue(msg.startswith("DateTimeField Event.dt received "
|
||||
"a naive datetime"))
|
||||
event = Event.objects.get()
|
||||
# microseconds are lost during a round-trip in the database
|
||||
# naive datetimes are interpreted in local time
|
||||
self.assertEqual(event.dt, dt.replace(microsecond=0, tzinfo=EAT))
|
||||
|
||||
def test_aware_datetime_in_local_timezone(self):
|
||||
dt = datetime.datetime(2011, 9, 1, 13, 20, 30, tzinfo=EAT)
|
||||
Event.objects.create(dt=dt)
|
||||
event = Event.objects.get()
|
||||
self.assertEqual(event.dt, dt)
|
||||
|
||||
@skipUnlessDBFeature('supports_microsecond_precision')
|
||||
def test_aware_datetime_in_local_timezone_with_microsecond(self):
|
||||
dt = datetime.datetime(2011, 9, 1, 13, 20, 30, 405060, tzinfo=EAT)
|
||||
Event.objects.create(dt=dt)
|
||||
event = Event.objects.get()
|
||||
self.assertEqual(event.dt, dt)
|
||||
|
||||
@skipIfDBFeature('supports_microsecond_precision')
|
||||
def test_aware_datetime_in_local_timezone_with_microsecond_unsupported(self):
|
||||
dt = datetime.datetime(2011, 9, 1, 13, 20, 30, 405060, tzinfo=EAT)
|
||||
Event.objects.create(dt=dt)
|
||||
event = Event.objects.get()
|
||||
# microseconds are lost during a round-trip in the database
|
||||
self.assertEqual(event.dt, dt.replace(microsecond=0))
|
||||
|
||||
def test_aware_datetime_in_utc(self):
|
||||
dt = datetime.datetime(2011, 9, 1, 10, 20, 30, tzinfo=UTC)
|
||||
Event.objects.create(dt=dt)
|
||||
|
|
Loading…
Reference in New Issue