diff --git a/django/db/models/functions/datetime.py b/django/db/models/functions/datetime.py index 02d92a9a07c..baed94227af 100644 --- a/django/db/models/functions/datetime.py +++ b/django/db/models/functions/datetime.py @@ -241,18 +241,14 @@ class TruncBase(TimezoneMixin, Transform): kind = None tzinfo = None - # RemovedInDjango50Warning: when the deprecation ends, remove is_dst - # argument. def __init__( self, expression, output_field=None, tzinfo=None, - is_dst=timezone.NOT_PASSED, **extra, ): self.tzinfo = tzinfo - self.is_dst = is_dst super().__init__(expression, output_field=output_field, **extra) def as_sql(self, compiler, connection): @@ -343,7 +339,7 @@ class TruncBase(TimezoneMixin, Transform): pass elif value is not None: value = value.replace(tzinfo=None) - value = timezone.make_aware(value, self.tzinfo, is_dst=self.is_dst) + value = timezone.make_aware(value, self.tzinfo) elif not connection.features.has_zoneinfo_database: raise ValueError( "Database returned an invalid datetime value. Are time " @@ -360,22 +356,16 @@ class TruncBase(TimezoneMixin, Transform): class Trunc(TruncBase): - - # RemovedInDjango50Warning: when the deprecation ends, remove is_dst - # argument. def __init__( self, expression, kind, output_field=None, tzinfo=None, - is_dst=timezone.NOT_PASSED, **extra, ): self.kind = kind - super().__init__( - expression, output_field=output_field, tzinfo=tzinfo, is_dst=is_dst, **extra - ) + super().__init__(expression, output_field=output_field, tzinfo=tzinfo, **extra) class TruncYear(TruncBase): diff --git a/django/db/models/query.py b/django/db/models/query.py index 13d24bb8716..c943cfe2193 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -1372,11 +1372,7 @@ class QuerySet(AltersData): .order_by(("-" if order == "DESC" else "") + "datefield") ) - # RemovedInDjango50Warning: when the deprecation ends, remove is_dst - # argument. - def datetimes( - self, field_name, kind, order="ASC", tzinfo=None, is_dst=timezone.NOT_PASSED - ): + def datetimes(self, field_name, kind, order="ASC", tzinfo=None): """ Return a list of datetime objects representing all available datetimes for the given field_name, scoped to 'kind'. @@ -1400,7 +1396,6 @@ class QuerySet(AltersData): kind, output_field=DateTimeField(), tzinfo=tzinfo, - is_dst=is_dst, ), plain_field=F(field_name), ) diff --git a/django/utils/timezone.py b/django/utils/timezone.py index 73813fa20ee..eff91667ec9 100644 --- a/django/utils/timezone.py +++ b/django/utils/timezone.py @@ -37,9 +37,6 @@ __all__ = [ # noqa for utc RemovedInDjango50Warning. "make_naive", ] -# RemovedInDjango50Warning: sentinel for deprecation of is_dst parameters. -NOT_PASSED = object() - def __getattr__(name): if name != "utc": @@ -259,17 +256,8 @@ def is_naive(value): return value.utcoffset() is None -def make_aware(value, timezone=None, is_dst=NOT_PASSED): +def make_aware(value, timezone=None): """Make a naive datetime.datetime in a given time zone aware.""" - if is_dst is NOT_PASSED: - is_dst = None - else: - warnings.warn( - "The is_dst argument to make_aware(), used by the Trunc() " - "database functions and QuerySet.datetimes(), is deprecated as it " - "has no effect with zoneinfo time zones.", - RemovedInDjango50Warning, - ) if timezone is None: timezone = get_current_timezone() # Check that we won't overwrite the timezone of an aware datetime. diff --git a/docs/ref/models/database-functions.txt b/docs/ref/models/database-functions.txt index 71c98fd73e5..78239be2f54 100644 --- a/docs/ref/models/database-functions.txt +++ b/docs/ref/models/database-functions.txt @@ -503,7 +503,7 @@ Usage example:: ``Trunc`` --------- -.. class:: Trunc(expression, kind, output_field=None, tzinfo=None, is_dst=None, **extra) +.. class:: Trunc(expression, kind, output_field=None, tzinfo=None, **extra) Truncates a date up to a significant component. @@ -521,14 +521,6 @@ value. If ``output_field`` is omitted, it will default to the ``output_field`` of ``expression``. A ``tzinfo`` subclass, usually provided by :mod:`zoneinfo`, can be passed to truncate a value in a specific timezone. -.. deprecated:: 4.0 - - The ``is_dst`` parameter indicates whether or not ``pytz`` should interpret - nonexistent and ambiguous datetimes in daylight saving time. By default - (when ``is_dst=None``), ``pytz`` raises an exception for such datetimes. - - The ``is_dst`` parameter is deprecated and will be removed in Django 5.0. - Given the datetime ``2015-06-15 14:30:50.000321+00:00``, the built-in ``kind``\s return: @@ -594,28 +586,24 @@ Usage example:: ``DateField`` truncation ~~~~~~~~~~~~~~~~~~~~~~~~ -.. class:: TruncYear(expression, output_field=None, tzinfo=None, is_dst=None, **extra) +.. class:: TruncYear(expression, output_field=None, tzinfo=None, **extra) .. attribute:: kind = 'year' -.. class:: TruncMonth(expression, output_field=None, tzinfo=None, is_dst=None, **extra) +.. class:: TruncMonth(expression, output_field=None, tzinfo=None, **extra) .. attribute:: kind = 'month' -.. class:: TruncWeek(expression, output_field=None, tzinfo=None, is_dst=None, **extra) +.. class:: TruncWeek(expression, output_field=None, tzinfo=None, **extra) Truncates to midnight on the Monday of the week. .. attribute:: kind = 'week' -.. class:: TruncQuarter(expression, output_field=None, tzinfo=None, is_dst=None, **extra) +.. class:: TruncQuarter(expression, output_field=None, tzinfo=None, **extra) .. attribute:: kind = 'quarter' -.. deprecated:: 4.0 - - The ``is_dst`` parameter is deprecated and will be removed in Django 5.0. - These are logically equivalent to ``Trunc('date_field', kind)``. They truncate all parts of the date up to ``kind`` which allows grouping or filtering dates with less precision. ``expression`` can have an ``output_field`` of either @@ -675,26 +663,22 @@ truncate function. It's also registered as a transform on ``DateTimeField`` as truncate function. It's also registered as a transform on ``DateTimeField`` as ``__time``. -.. class:: TruncDay(expression, output_field=None, tzinfo=None, is_dst=None, **extra) +.. class:: TruncDay(expression, output_field=None, tzinfo=None, **extra) .. attribute:: kind = 'day' -.. class:: TruncHour(expression, output_field=None, tzinfo=None, is_dst=None, **extra) +.. class:: TruncHour(expression, output_field=None, tzinfo=None, **extra) .. attribute:: kind = 'hour' -.. class:: TruncMinute(expression, output_field=None, tzinfo=None, is_dst=None, **extra) +.. class:: TruncMinute(expression, output_field=None, tzinfo=None, **extra) .. attribute:: kind = 'minute' -.. class:: TruncSecond(expression, output_field=None, tzinfo=None, is_dst=None, **extra) +.. class:: TruncSecond(expression, output_field=None, tzinfo=None, **extra) .. attribute:: kind = 'second' -.. deprecated:: 4.0 - - The ``is_dst`` parameter is deprecated and will be removed in Django 5.0. - These are logically equivalent to ``Trunc('datetime_field', kind)``. They truncate all parts of the date up to ``kind`` and allow grouping or filtering datetimes with less precision. ``expression`` must have an ``output_field`` of @@ -728,25 +712,21 @@ Usage example:: ``TimeField`` truncation ~~~~~~~~~~~~~~~~~~~~~~~~ -.. class:: TruncHour(expression, output_field=None, tzinfo=None, is_dst=None, **extra) +.. class:: TruncHour(expression, output_field=None, tzinfo=None, **extra) :noindex: .. attribute:: kind = 'hour' -.. class:: TruncMinute(expression, output_field=None, tzinfo=None, is_dst=None, **extra) +.. class:: TruncMinute(expression, output_field=None, tzinfo=None, **extra) :noindex: .. attribute:: kind = 'minute' -.. class:: TruncSecond(expression, output_field=None, tzinfo=None, is_dst=None, **extra) +.. class:: TruncSecond(expression, output_field=None, tzinfo=None, **extra) :noindex: .. attribute:: kind = 'second' -.. deprecated:: 4.0 - - The ``is_dst`` parameter is deprecated and will be removed in Django 5.0. - These are logically equivalent to ``Trunc('time_field', kind)``. They truncate all parts of the time up to ``kind`` which allows grouping or filtering times with less precision. ``expression`` can have an ``output_field`` of either diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt index e3ce38066e2..4a1836ba14e 100644 --- a/docs/ref/models/querysets.txt +++ b/docs/ref/models/querysets.txt @@ -837,7 +837,7 @@ Examples:: ``datetimes()`` ~~~~~~~~~~~~~~~ -.. method:: datetimes(field_name, kind, order='ASC', tzinfo=None, is_dst=None) +.. method:: datetimes(field_name, kind, order='ASC', tzinfo=None) Returns a ``QuerySet`` that evaluates to a list of :class:`datetime.datetime` objects representing all available dates of a particular kind within the @@ -859,14 +859,6 @@ object. If it's ``None``, Django uses the :ref:`current time zone `. It has no effect when :setting:`USE_TZ` is ``False``. -``is_dst`` indicates whether or not ``pytz`` should interpret nonexistent and -ambiguous datetimes in daylight saving time. By default (when ``is_dst=None``), -``pytz`` raises an exception for such datetimes. - -.. deprecated:: 4.0 - - The ``is_dst`` parameter is deprecated and will be removed in Django 5.0. - .. _database-time-zone-definitions: .. note:: diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt index de7f0d1259f..2a8a8357fb8 100644 --- a/docs/ref/utils.txt +++ b/docs/ref/utils.txt @@ -972,38 +972,13 @@ appropriate entities. Returns ``True`` if ``value`` is naive, ``False`` if it is aware. This function assumes that ``value`` is a :class:`~datetime.datetime`. -.. function:: make_aware(value, timezone=None, is_dst=None) +.. function:: make_aware(value, timezone=None) Returns an aware :class:`~datetime.datetime` that represents the same point in time as ``value`` in ``timezone``, ``value`` being a naive :class:`~datetime.datetime`. If ``timezone`` is set to ``None``, it defaults to the :ref:`current time zone `. - .. deprecated:: 4.0 - - When using ``pytz``, the ``pytz.AmbiguousTimeError`` exception is - raised if you try to make ``value`` aware during a DST transition where - the same time occurs twice (when reverting from DST). Setting - ``is_dst`` to ``True`` or ``False`` will avoid the exception by - choosing if the time is pre-transition or post-transition respectively. - - When using ``pytz``, the ``pytz.NonExistentTimeError`` exception is - raised if you try to make ``value`` aware during a DST transition such - that the time never occurred. For example, if the 2:00 hour is skipped - during a DST transition, trying to make 2:30 aware in that time zone - will raise an exception. To avoid that you can use ``is_dst`` to - specify how ``make_aware()`` should interpret such a nonexistent time. - If ``is_dst=True`` then the above time would be interpreted as 2:30 DST - time (equivalent to 1:30 local time). Conversely, if ``is_dst=False`` - the time would be interpreted as 2:30 standard time (equivalent to 3:30 - local time). - - The ``is_dst`` parameter has no effect when using non-``pytz`` timezone - implementations. - - The ``is_dst`` parameter is deprecated and will be removed in Django - 5.0. - .. function:: make_naive(value, timezone=None) Returns a naive :class:`~datetime.datetime` that represents in diff --git a/docs/releases/5.0.txt b/docs/releases/5.0.txt index f137c27398d..2a0918b2879 100644 --- a/docs/releases/5.0.txt +++ b/docs/releases/5.0.txt @@ -280,6 +280,20 @@ to remove usage of these features. * Support for ``pytz`` timezones is removed. +* The ``is_dst`` argument is removed from: + + * ``QuerySet.datetimes()`` + * ``django.utils.timezone.make_aware()`` + * ``django.db.models.functions.Trunc()`` + * ``django.db.models.functions.TruncSecond()`` + * ``django.db.models.functions.TruncMinute()`` + * ``django.db.models.functions.TruncHour()`` + * ``django.db.models.functions.TruncDay()`` + * ``django.db.models.functions.TruncWeek()`` + * ``django.db.models.functions.TruncMonth()`` + * ``django.db.models.functions.TruncQuarter()`` + * ``django.db.models.functions.TruncYear()`` + See :ref:`deprecated-features-4.1` for details on these changes, including how to remove usage of these features. diff --git a/tests/utils_tests/test_timezone.py b/tests/utils_tests/test_timezone.py index 6ec88285618..931347ad46b 100644 --- a/tests/utils_tests/test_timezone.py +++ b/tests/utils_tests/test_timezone.py @@ -8,7 +8,6 @@ except ImportError: from django.test import SimpleTestCase, override_settings from django.utils import timezone -from django.utils.deprecation import RemovedInDjango50Warning PARIS_ZI = zoneinfo.ZoneInfo("Europe/Paris") EAT = timezone.get_fixed_timezone(180) # Africa/Nairobi @@ -226,17 +225,6 @@ class TimezoneTests(SimpleTestCase): self.assertEqual(std.utcoffset(), datetime.timedelta(hours=1)) self.assertEqual(dst.utcoffset(), datetime.timedelta(hours=2)) - def test_make_aware_is_dst_deprecation_warning(self): - msg = ( - "The is_dst argument to make_aware(), used by the Trunc() " - "database functions and QuerySet.datetimes(), is deprecated as it " - "has no effect with zoneinfo time zones." - ) - with self.assertRaisesMessage(RemovedInDjango50Warning, msg): - timezone.make_aware( - datetime.datetime(2011, 9, 1, 13, 20, 30), EAT, is_dst=True - ) - def test_get_timezone_name(self): """ The _get_timezone_name() helper must return the offset for fixed offset