Hello,
This week, I've gathered all the information I need about how the database
engines and adapters supported by Django handle datetime objects. I'm attaching
my findings.
The good news is that the database representations currently used by Django are
already optimal for my proposal. I'll store data in UTC:
- with an explicit timezone on PostgreSQL,
- without timezone on SQLite and MySQL because the database engine doesn't
support it,
- without timezone on Oracle because the database adapter doesn't support it.
Currently, Django sets the "supports_timezones feature" to True for SQLite. I'm
skeptical about this choice. Indeed, the time zone is stored: SQLite just saves
the output of ".isoformat(), which includes the UTC offset for aware
datetime objects. However, the timezone information is ignored when reading the
data back from the database, thus yielding incorrect data when it's different
from the local time defined by settings.TIME_ZONE.
As far as I can tell, the "supports_timezones" and the
"needs_datetime_string_cast" database features are incompatible, at least with
the current implementation of "typecast_timestamp". There's a comment about
this problem that dates back to the merge of magic-removal, possibly before:
https://code.djangoproject.com/browser/django/trunk/django/db/backends/util.py?annotate=blame#L79
SQLite is the only engine who has these two flags set to True. I think
"supports_timezones" should be False. Does anyone know why it's True? Is it
just an historical artifact?
Finally, I have read the document that describes "to_python",
"value_to_string", and r"get_(db_)?prep_(value|save|lookup)". The next step is
to adjust these functions in DateFieldField, depending on the value of
settings.USE_TZ.
Best regards,
--
Aymeric Augustin.
On 11 sept. 2011, at 23:18, Aymeric Augustin wrote:
> Hello,
>
> Given the positive feedback received here and on IRC, I've started the
> implementation.
>
> Being most familiar with mercurial, I've forked the Bitbucket mirror. This
> page that compares my branch to trunk:
> https://bitbucket.org/aaugustin/django/compare/..django/django
>
> I've read a lot of code in django.db, and also the documentation of
> PostgreSQL, MySQL and SQLite regarding date/time types.
>
> I've written some tests that validate the current behavior of Django. Their
> goal is to guarantee backwards-compatibility when USE_TZ = False.
>
> At first they failed because runtests.py doesn't set os.environ['TZ'] and
> doesn't call time.tzset(), so the tests ran with my system local time. I
> fixed that in setUp and tearDown. Maybe we should call them in runtests.py
> too for consistency?
>
> By the way, since everything is supposed to be in UTC internally when USE_TZ
> is True, it is theoretically to get rid of os.environ['TZ'] and time.tzset().
> They are only useful to make timezone-dependant functions respect the
> TIME_ZONE setting. However, for backwards compatibility (in particular with
> third-party apps), it's better to keep them and interpret naive datetimes in
> the timezone defined by settings.TIME_ZONE (instead of rejecting them
> outright). For this reason, I've decided to keep os.environ['TZ'] and
> time.tzset() even when USE_TZ is True.
>
> Best regards,
>
> --
> Aymeric Augustin.
>
>
> On 3 sept. 2011, at 17:40, Aymeric Augustin wrote:
>
>> Hello,
>>
>> The GSoC proposal "Multiple timezone support for datetime representation"
>> wasn't picked up in 2011 and 2010. Although I'm not a student and the summer
>> is over, I'd like to tackle this problem, and I would appreciate it very
>> much if a core developer accepted to mentor me during this work, GSoC-style.
>>
>> Here is my proposal, following the GSoC guidelines. I apologize for the wall
>> of text; this has been discussed many times in the past 4 years and I've
>> tried to address as many concerns and objections as possible.
>>
>> Definition of success
>> -
>>
>> The goal is to resolve ticket #2626 in Django 1.4 or 1.5 (depending on when
>> 1.4 is released).
>>
>> Design specification
>>
>>
>> Some background on timezones in Django and Python
>> .
>>
>> Currently, Django stores datetime objects in local time in the database,
>> local time being defined by the TIME_ZONE setting. It retrieves them as
>> naive datetime objects. As a consequence, developers work with naive
>> datetime objects in local time.
>>
>> This approach sort of works when all the users are in the same timezone and
>> don't care about data loss (inconsistencies) when DST kicks in or out.
>> Unfortunately, these assumptions aren't true for many Django projects: for
>> instance, one may want to log sessions (login/logout) for security purposes:
>> that's a 24/7 flow of important data. Read tickets #2626 and #10587 for more
>> details.
>>
>> Python's standard library provides limited sup