From 8bbecaa817f48c6d1759fbbdeb90ea57a7af1892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 21 Oct 2021 00:11:57 +0200 Subject: [PATCH] Allow to cast as date using timezone issue10860 review372321002 --- CHANGELOG | 1 + doc/ref/models/fields.rst | 7 +++++++ trytond/model/fields/date.py | 7 +++++-- trytond/tests/test_field_date.py | 19 +++++++++++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index ffdda448c6..038ed7b9c7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Allow to cast to date with timezone * Support create/delete attribute in view * Skip default values when copying records * Use global cache for Function fields in readonly transactions diff --git a/doc/ref/models/fields.rst b/doc/ref/models/fields.rst index 434b90efe1..8e6a6ac831 100644 --- a/doc/ref/models/fields.rst +++ b/doc/ref/models/fields.rst @@ -408,6 +408,13 @@ Date A date, represented in Python by a ``datetime.date`` instance. +Instance methods: + +.. method:: Field.sql_cast(expression[, timezone]) + + Return the SQL expression cast as date. + If timezone is set the expression is first converted to this timezone. + DateTime -------- diff --git a/trytond/model/fields/date.py b/trytond/model/fields/date.py index 9435f511c1..461b69b3bd 100644 --- a/trytond/model/fields/date.py +++ b/trytond/model/fields/date.py @@ -2,7 +2,7 @@ # this repository contains the full copyright notices and license terms. import datetime -from sql.functions import Function +from sql.functions import Function, AtTimeZone from trytond import backend from trytond.pyson import PYSONEncoder @@ -41,9 +41,12 @@ class Date(Field): raise ValueError("Date field can not have time") return super().sql_format(value) - def sql_cast(self, expression): + def sql_cast(self, expression, timezone=None): if backend.name == 'sqlite': return SQLite_Date(expression) + if timezone: + expression = AtTimeZone(expression, 'utc') + expression = AtTimeZone(expression, timezone) return super(Date, self).sql_cast(expression) diff --git a/trytond/tests/test_field_date.py b/trytond/tests/test_field_date.py index 6bd3007a6d..ebe2916796 100644 --- a/trytond/tests/test_field_date.py +++ b/trytond/tests/test_field_date.py @@ -3,11 +3,14 @@ import datetime import unittest +from sql import Literal, Select from sql.functions import CurrentDate +from trytond import backend from trytond.model.exceptions import RequiredValidationError from trytond.pool import Pool from trytond.tests.test_tryton import activate_module, with_transaction +from trytond.transaction import Transaction today = datetime.date(2009, 1, 1) tomorrow = today + datetime.timedelta(1) @@ -442,6 +445,22 @@ class FieldDateTestCase(unittest.TestCase): 'date': datetime.datetime(2009, 1, 1, 12, 0), }) + @unittest.skipIf(backend.name == 'sqlite', + "SQLite does not support timezone others than utc and localtime") + @with_transaction() + def test_sql_cast_timezone(self): + "Cast datetime to date with timezone" + Date = Pool().get('test.date') + expression = Date.date.sql_cast( + Literal(datetime.datetime(2021, 10, 14, 22, 00)), + timezone='Europe/Brussels') + cursor = Transaction().connection.cursor() + + cursor.execute(*Select([expression])) + result, = cursor.fetchone() + + self.assertEqual(result, datetime.date(2021, 10, 15)) + def suite(): return unittest.TestLoader().loadTestsFromTestCase(FieldDateTestCase)