Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#31608 closed Bug (fixed)

forms.DateTimeField parses ISO 8601 datetime with offset as aware when USE_TZ is False.

Reported by: Carlton Gibson Owned by: Hasan Ramezani
Component: Forms Version: 3.1
Severity: Release blocker Keywords:
Cc: Claude Paroz Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


The following test fails on 3.1a1.

USE_TZ: If this is set to True, Django will use timezone-aware datetimes internally. Otherwise, Django will use naive datetimes in local time.

diff --git a/tests/forms_tests/field_tests/ b/tests/forms_tests/field_tests/
index f0e6ada3c5..ed035497d8 100644
--- a/tests/forms_tests/field_tests/
+++ b/tests/forms_tests/field_tests/
@@ -2,8 +2,8 @@ from datetime import date, datetime
 from django.core.exceptions import ValidationError
 from django.forms import DateTimeField
-from django.test import SimpleTestCase
-from django.utils.timezone import get_fixed_timezone, utc
+from django.test import SimpleTestCase, override_settings
+from django.utils.timezone import get_fixed_timezone, is_naive, utc
 class DateTimeFieldTest(SimpleTestCase):
@@ -65,6 +65,12 @@ class DateTimeFieldTest(SimpleTestCase):
             with self.subTest(value=value):
                 self.assertEqual(f.clean(value), expected_datetime)
+    @override_settings(USE_TZ=False)
+    def test_use_tz_false(self):
+        f = DateTimeField()
+        value = '2014-09-23T22:34Z'
+        self.assertTrue(is_naive(f.clean(value)))
     def test_datetimefield_clean_invalid(self):
         f = DateTimeField()
         msg = "'Enter a valid date/time.'"

Expected behaviour is to return a naive datetime.

Change History (9)

comment:1 by Mariusz Felisiak, 4 years ago

Cc: Claude Paroz added
Triage Stage: UnreviewedAccepted

comment:2 by Hasan Ramezani, 4 years ago

Has patch: set
Owner: changed from nobody to Hasan Ramezani
Status: newassigned

comment:3 by Claude Paroz, 4 years ago

Repeating what I said on the PR. In my opinion, even if USE_TZ is False, parsing a datetime including timezone information should really keep its timezone. So I'd rather add an admonition to the docs.

comment:4 by Carlton Gibson, 4 years ago

So this caused a test failure on Django-Filter.

I've adjusted the test case there to account for the new behaviour.

-    @override_settings(USE_TZ=False)
     def test_clean(self):
         w = RangeWidget()
         f = IsoDateTimeRangeField(widget=w)
-        self.assertEqual(
-            f.clean(['2015-01-01T10:30:01.123000+01:00', '2015-01-10T08:45:02.345000+01:00']),
-            slice(datetime(2015, 1, 1, 9, 30, 1, 123000),
-                  datetime(2015, 1, 10, 7, 45, 2, 345000)))
+        expected = slice(
+            datetime(2015, 1, 1, 9, 30, 1, 123000, tzinfo=timezone.utc),
+            datetime(2015, 1, 10, 7, 45, 2, 345000, tzinfo=timezone.utc)
+        )
+        actual = f.clean(['2015-01-01T10:30:01.123000+01:00', '2015-01-10T08:45:02.345000+01:00'])
+        self.assertEqual(expected, actual)

Let's assume we'll go with the docs change.

comment:5 by Hasan Ramezani, 4 years ago

Ok, I will create a PR for doc change.

comment:6 by Hasan Ramezani, 4 years ago

I created a new PR to change the release note and mention the behavior of forms.DateTimeField per Carlton comment.

comment:7 by Carlton Gibson, 4 years ago

Triage Stage: AcceptedReady for checkin

comment:8 by GitHub <noreply@…>, 4 years ago

Resolution: fixed
Status: assignedclosed

In 643207ef:

Fixed #31608 -- Doc'd that form ISO 8601 datetime parsing always retains tzinfo.

comment:9 by Carlton Gibson <carlton.gibson@…>, 4 years ago

In a6c773a:

[3.1.x] Fixed #31608 -- Doc'd that form ISO 8601 datetime parsing always retains tzinfo.

Backport of 643207efaebbff4e7c3ebcbf9ca49fb6197137e1 from master

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