Opened 6 years ago

Last modified 5 years ago

#29754 closed New feature

Trunc() doesn't handle NonExistingTimeError/AmbiguousTimeError — at Initial Version

Reported by: Alexander Holmbäck Owned by: nobody
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords: pytz, Trunc, is_dst
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When Trunc() truncates to a nonexisting or ambiguous datetime, the exception raised by pytz remains unhandled. The expected behavior would, IMO, be to use naive datetimes for truncated dates, or adjust to closest existing non-ambiguous datetime.

This test for example:

import datetime
import pytz

from django.db.models.functions import Trunc
from django.test import TestCase
from django.utils import timezone

from .models import Log


class TestTruncateToNonExistingTime(TestCase):

    def test_truncate_to_dst_ends_stockholm(self):
        tzinfo = pytz.timezone('Europe/Stockholm')
        timestamp = datetime.datetime(2018, 10, 28, 2, tzinfo=tzinfo)
        Log.objects.create(timestamp=timestamp)
        logs = Log.objects.annotate(day=Trunc('timestamp', 'hour')).all()

        timezone.activate(tzinfo)
        self.assertEqual(logs[0].day.day, 28)

Results in the following error:

======================================================================
ERROR: test_truncate_to_dst_ends_stockholm (trunc.tests.TestTruncateToNonExistingTime)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/alex/tickets/trunc/tests.py", line 47, in test_truncate_to_dst_ends_stockholm
    self.assertEqual(logs[0].day.day, 28)
  File "/home/alex/django/django/db/models/query.py", line 303, in __getitem__
    qs._fetch_all()
  File "/home/alex/django/django/db/models/query.py", line 1190, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "/home/alex/django/django/db/models/query.py", line 64, in __iter__
    for row in compiler.results_iter(results):
  File "/home/alex/django/django/db/models/sql/compiler.py", line 1013, in apply_converters
    value = converter(value, expression, connection)
  File "/home/alex/django/django/db/models/functions/datetime.py", line 225, in convert_value
    value = timezone.make_aware(value, self.tzinfo)
  File "/home/alex/django/django/utils/timezone.py", line 270, in make_aware
    return timezone.localize(value, is_dst=is_dst)
  File "/home/alex/.virtualenvs/djangodev/lib/python3.6/site-packages/pytz/tzinfo.py", line 363, in localize
    raise AmbiguousTimeError(dt)
pytz.exceptions.AmbiguousTimeError: 2018-10-28 02:00:00

Change History (0)

Note: See TracTickets for help on using tickets.
Back to Top