Opened 2 years ago

Closed 19 months ago

Last modified 19 months ago

#19371 closed Bug (invalid)

django.forms.DateTimeField does not properly handle aware datetimes as inputs

Reported by: delinhabit Owned by: aaugustin
Component: Forms Version: 1.4
Severity: Normal Keywords: forms, DateTimeField, timezones
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

If you have aware datetimes as inputs to a Form or ModelForm the cleaned values are localized to the local timezone discarding the timezone information that is part of the input data.

For a better understanding of the use case I have created a small test case (attached) to regress the issue.

Attachments (1)

tzbug.py (1.8 KB) - added by delinhabit 2 years ago.
regression tests (only need Django to be installed and $ python tzbug.py)

Download all attachments as: .zip

Change History (5)

Changed 2 years ago by delinhabit

regression tests (only need Django to be installed and $ python tzbug.py)

comment:1 Changed 2 years ago by aaugustin

  • Needs documentation unset
  • Needs tests unset
  • Owner changed from nobody to aaugustin
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Design decision needed
  • Type changed from Uncategorized to Bug

comment:2 Changed 2 years ago by aaugustin

  • Triage Stage changed from Design decision needed to Accepted

The forms fields aren't designed to handle aware datetimes. The input should be rejected as invalid, because it doesn't match any of DATETIME_INPUT_FORMATS. I don't why it's accepted without an error.

comment:3 Changed 19 months ago by aaugustin

  • Resolution set to invalid
  • Status changed from new to closed

On current master the test case attached to the ticket doesn't pass validation, as expected.

So I can't reproduce the behavior described in the report:

the cleaned values are localized to the local timezone discarding the timezone information.

I don't remember if I had verified it when I accepted the ticket; probably not.

% DJANGO_SETTINGS_MODULE=test_sqlite python tzbug.py
FF.
======================================================================
FAIL: test_aware_datetime_with_form (__main__.TimezonesBugTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/myk/Documents/dev/django/django/test/utils.py", line 220, in inner
    return test_func(*args, **kwargs)
  File "tzbug.py", line 39, in test_aware_datetime_with_form
    self.assertTrue(form.is_valid())
AssertionError: False is not true

======================================================================
FAIL: test_aware_datetime_with_modelform (__main__.TimezonesBugTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/myk/Documents/dev/django/django/test/utils.py", line 220, in inner
    return test_func(*args, **kwargs)
  File "tzbug.py", line 48, in test_aware_datetime_with_modelform
    self.assertTrue(form.is_valid())
AssertionError: False is not true

----------------------------------------------------------------------
Ran 3 tests in 0.023s

FAILED (failures=2)

Supporting this use case would require drastic changes. Currently Django attempts to parse the value with strptime for each format declared in DATETIME_INPUT_FORMATS (or its equivalent for the current locale). But strptime can't parse timezones:

>>> import datetime
>>> datetime.datetime.strptime("2013-09-21 21:02:46", "%Y-%m-%d %H:%M:%S")
datetime.datetime(2013, 9, 21, 21, 2, 46)
>>> datetime.datetime.strptime("2013-09-21 21:02:46+02:00", "%Y-%m-%d %H:%M:%S%z")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/_strptime.py", line 317, in _strptime
    (bad_directive, format))
ValueError: 'z' is a bad directive in format '%Y-%m-%d %H:%M:%S%z'

Django's built-in DateTimeField doesn't expose time zone information to the end user.

If you want to expose it, I think you have to write a custom field. It isn't very hard.

comment:4 Changed 19 months ago by Aymeric Augustin <aymeric.augustin@…>

In 68b10fa1776f927180dd20f4818b5e6e07537615:

Ensured that explicit time zones are rejected by forms.

Refs #19371.

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