#19371 closed Bug (invalid)
django.forms.DateTimeField does not properly handle aware datetimes as inputs
| Reported by: | Ion Scerbatiuc | Owned by: | Aymeric Augustin | 
|---|---|---|---|
| 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)
Change History (5)
by , 13 years ago
comment:1 by , 13 years ago
| Owner: | changed from to | 
|---|---|
| Triage Stage: | Unreviewed → Design decision needed | 
| Type: | Uncategorized → Bug | 
comment:2 by , 13 years ago
| Triage Stage: | Design decision needed → 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 by , 12 years ago
| Resolution: | → invalid | 
|---|---|
| Status: | new → 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.
regression tests (only need Django to be installed and $ python tzbug.py)