#34699: Filtering on annotated TruncSecond expression gives unexpected result.
-------------------------------------+-------------------------------------
Reporter: Stefan | Owner: Wes P.
Type: | Status: assigned
Cleanup/optimization |
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Natalia Bidart):
* cc: Simon Charette, David, Sanders (added)
* needs_better_patch: 0 => 1
* version: 4.2 => dev
Comment:
Thank you Wes for working on this ticket. I think the PR needs some
adjusting in terms of docs and code formatting, but before getting into
those, details, I would like to first define a plan in what would desired
in terms of fixing this ticket.
To refresh my memory, I have re-read the docs and tried the reproducing
examples again. I still think there is an unexpected result when calling
any of the truncation functions (when there is a `TIME_ZONE` defined in
the Django project). Following the case by case explanation in
[https://docs.djangoproject.com/en/dev/ref/models/database-
functions/#trunc these docs]:
> Trunc takes a single expression, representing a DateField, TimeField, or
DateTimeField, a kind representing a date or time part, and an
output_field that’s either DateTimeField(), TimeField(), or DateField().
It returns a datetime, date, or time depending on output_field, with
fields up to kind set to their minimum value. If output_field is omitted,
it will default to the output_field of expression. A tzinfo subclass,
usually provided by zoneinfo, can be passed to truncate a value in a
specific timezone.
To me, the above paragraph does not imply that the `tzinfo` SHOULD be
passed to get results that make sense in the context of a custom project-
wide`TIME_ZONE`. Moreover, I have transformed the example that follows
that paragraph into a test case (PostgreSQL only) and I get test failures
for all of the `Australia/Melbourne` cases because the truncated date is
in `UTC`:
{{{#!python
class Ticket34699Tests(TestCase):
def test_docs_example(self):
self.assertSequenceEqual(DTModel.objects.all(), [])
dt = datetime.datetime(2015,6, 15, 14, 30, 50, 321,
zoneinfo.ZoneInfo("UTC"))
# From the docs: Given the datetime 2015-06-15
14:30:50.000321+00:00...
docs_dt = "2015-06-15T14:30:50.000321+00:00"
self.assertEqual(dt.isoformat(), docs_dt)
utc = {
"year": "2015-01-01T00:00:00+00:00",
"quarter": "2015-04-01T00:00:00+00:00",
"month": "2015-06-01T00:00:00+00:00",
"week": "2015-06-15T00:00:00+00:00",
"day": "2015-06-15T00:00:00+00:00",
"hour": "2015-06-15T14:00:00+00:00",
"minute": "2015-06-15T14:30:00+00:00",
"second": "2015-06-15T14:30:50+00:00",
}
melbourne = {
"year": "2015-01-01T00:00:00+11:00",
"quarter": "2015-04-01T00:00:00+10:00",
"month": "2015-06-01T00:00:00+10:00",
"week": "2015-06-16T00:00:00+10:00",
"day": "2015-06-16T00:00:00+10:00",
"hour": "2015-06-16T00:00:00+10:00",
"minute": "2015-06-16T00:30:00+10:00",
"second": "2015-06-16T00:30:50+10:00",
}
for tz, cases in [("UTC", utc), ("Australia/Melbourne",
melbourne)]:
for kind, expected in cases.items():
with (self.settings(USE_TZ=True, TIME_ZONE="UTC"),
self.subTest(kind=kind, tz=tz)):
instance = DTModel.objects.create(start_datetime=dt)
self.assertEqual(instance.start_datetime.isoformat(),
docs_dt)
result = DTModel.objects.annotate(
truncated=Trunc("start_datetime", kind,
output_field=DateTimeField())
).get()
self.assertEqual(result.truncated.isoformat(),
expected)
DTModel.objects.all().delete()
}}}
If we are looking for a docs-only fix at this stage, I think we need to do
a heavier rework of these docs, to be much more upfront about the need to
pass `tzinfo` to get expected results for any project with a custom
`TIME_ZONE`. Personally I feel the code should behave differently, but I
don't see clearly how such fix would look or we would handle the potential
deprecation/behavior change.
Simon, David, would you have further thoughts?
--
Ticket URL: <https://code.djangoproject.com/ticket/34699#comment:16>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/django-updates/0107019611768af2-1e6903ef-9488-444c-8993-ea27e878edf7-000000%40eu-central-1.amazonses.com.