summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Jackson <cpmhjoe@gmail.com>2020-08-29 14:40:54 -0400
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-09-02 07:42:27 +0200
commit9d5d865fd6e989abe60fdf02e7f97fd4d98178a4 (patch)
treea2026e2afe2c73c4e149de3cde0a3dbf050c2ae1
parent76e0151ea0e0f56dca66cee846a78b89346d2c4c (diff)
Fixed #31948 -- Added tzinfo parameter to TruncDate() and TruncTime().
-rw-r--r--AUTHORS1
-rw-r--r--django/db/models/functions/datetime.py4
-rw-r--r--docs/ref/models/database-functions.txt12
-rw-r--r--docs/releases/3.2.txt5
-rw-r--r--tests/db_functions/datetime/test_extract_trunc.py10
5 files changed, 28 insertions, 4 deletions
diff --git a/AUTHORS b/AUTHORS
index 16272bdf28..5c50598ddc 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -449,6 +449,7 @@ answer newbie questions, and generally made Django that much better:
Joao Oliveira <joaoxsouls@gmail.com>
Joao Pedro Silva <j.pedro004@gmail.com>
Joe Heck <http://www.rhonabwy.com/wp/>
+ Joe Jackson <joe@joejackson.me>
Joel Bohman <mail@jbohman.com>
Joel Heenan <joelh-django@planetjoel.com>
Joel Watts <joel@joelwatts.com>
diff --git a/django/db/models/functions/datetime.py b/django/db/models/functions/datetime.py
index b6594b043b..6828980733 100644
--- a/django/db/models/functions/datetime.py
+++ b/django/db/models/functions/datetime.py
@@ -292,7 +292,7 @@ class TruncDate(TruncBase):
def as_sql(self, compiler, connection):
# Cast to date rather than truncate to date.
lhs, lhs_params = compiler.compile(self.lhs)
- tzname = timezone.get_current_timezone_name() if settings.USE_TZ else None
+ tzname = self.get_tzname()
sql = connection.ops.datetime_cast_date_sql(lhs, tzname)
return sql, lhs_params
@@ -305,7 +305,7 @@ class TruncTime(TruncBase):
def as_sql(self, compiler, connection):
# Cast to time rather than truncate to time.
lhs, lhs_params = compiler.compile(self.lhs)
- tzname = timezone.get_current_timezone_name() if settings.USE_TZ else None
+ tzname = self.get_tzname()
sql = connection.ops.datetime_cast_time_sql(lhs, tzname)
return sql, lhs_params
diff --git a/docs/ref/models/database-functions.txt b/docs/ref/models/database-functions.txt
index f5efdb7e87..3121a36fa9 100644
--- a/docs/ref/models/database-functions.txt
+++ b/docs/ref/models/database-functions.txt
@@ -623,20 +623,28 @@ that deal with date-parts can be used with ``DateField``::
``DateTimeField`` truncation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. class:: TruncDate(expression, **extra)
+.. class:: TruncDate(expression, tzinfo=None, **extra)
.. attribute:: lookup_name = 'date'
.. attribute:: output_field = DateField()
+ .. versionchanged:: 3.2
+
+ The ``tzinfo`` parameter was added.
+
``TruncDate`` casts ``expression`` to a date rather than using the built-in SQL
truncate function. It's also registered as a transform on ``DateTimeField`` as
``__date``.
-.. class:: TruncTime(expression, **extra)
+.. class:: TruncTime(expression, tzinfo=None, **extra)
.. attribute:: lookup_name = 'time'
.. attribute:: output_field = TimeField()
+ .. versionchanged:: 3.2
+
+ The ``tzinfo`` parameter was added.
+
``TruncTime`` casts ``expression`` to a time rather than using the built-in SQL
truncate function. It's also registered as a transform on ``DateTimeField`` as
``__time``.
diff --git a/docs/releases/3.2.txt b/docs/releases/3.2.txt
index d29a582d74..9017c33138 100644
--- a/docs/releases/3.2.txt
+++ b/docs/releases/3.2.txt
@@ -290,6 +290,11 @@ Models
distinct fields if there's only one field specified in
:meth:`.QuerySet.distinct`.
+* The new ``tzinfo`` parameter of the
+ :class:`~django.db.models.functions.TruncDate` and
+ :class:`~django.db.models.functions.TruncTime` database functions allows
+ truncating datetimes in a specific timezone.
+
Pagination
~~~~~~~~~~
diff --git a/tests/db_functions/datetime/test_extract_trunc.py b/tests/db_functions/datetime/test_extract_trunc.py
index f8ebb81cb5..f898ba5253 100644
--- a/tests/db_functions/datetime/test_extract_trunc.py
+++ b/tests/db_functions/datetime/test_extract_trunc.py
@@ -1124,14 +1124,24 @@ class DateFunctionWithTimeZoneTests(DateFunctionTests):
model = DTModel.objects.annotate(
melb_year=TruncYear('start_datetime', tzinfo=melb),
pacific_year=TruncYear('start_datetime', tzinfo=pacific),
+ melb_date=TruncDate('start_datetime', tzinfo=melb),
+ pacific_date=TruncDate('start_datetime', tzinfo=pacific),
+ melb_time=TruncTime('start_datetime', tzinfo=melb),
+ pacific_time=TruncTime('start_datetime', tzinfo=pacific),
).order_by('start_datetime').get()
+ melb_start_datetime = start_datetime.astimezone(melb)
+ pacific_start_datetime = start_datetime.astimezone(pacific)
self.assertEqual(model.start_datetime, start_datetime)
self.assertEqual(model.melb_year, truncate_to(start_datetime, 'year', melb))
self.assertEqual(model.pacific_year, truncate_to(start_datetime, 'year', pacific))
self.assertEqual(model.start_datetime.year, 2016)
self.assertEqual(model.melb_year.year, 2016)
self.assertEqual(model.pacific_year.year, 2015)
+ self.assertEqual(model.melb_date, melb_start_datetime.date())
+ self.assertEqual(model.pacific_date, pacific_start_datetime.date())
+ self.assertEqual(model.melb_time, melb_start_datetime.time())
+ self.assertEqual(model.pacific_time, pacific_start_datetime.time())
def test_trunc_ambiguous_and_invalid_times(self):
sao = pytz.timezone('America/Sao_Paulo')