Update, January 2013: Django 1.4 now has time zone support!!
Old answer for historical reasons:
I’m going to be working on this problem myself for my application. My first approach to this problem would be to go with django core developer Malcom Tredinnick’s advice in this django-user’s post. You’ll want to store the user’s timezone setting in their user profile, probably.
I would also highly encourage you to look into the pytz module, which makes working with timezones less painful. For the front end, I created a "timezone picker" based on the common timezones in pytz. I have one select box for the area, and another for the location (e.g. US/Central is rendered with two select boxes). It makes picking timezones slightly more convenient than wading through a list of 400+ choices.
It’s not that hard to write timezone aware code in django:
I’ve written simple django application which helps handle timezones issue in django projects: https://github.com/paluh/django-tz. It’s based on Brosner (django-timezone) code but takes different approach to solve the problem – I think it implements something similar to yours and FernandoEscher propositions.
All datetime values are stored in data base in one timezone (according to TIME_ZONE setting) and conversion to appropriate value (i.e. user timezone) are done in templates and forms (there is form widget for datetimes fields which contains additional subwidget with timezone). Every datetime conversion is explicit – no magic.
Additionally there is per thread cache which allows you simplify these datatime conversions (implementation is based on django i18n translation machinery).
When you want to remember user timezone, you should add timezone field to profile model and write simple middleware (follow the example from doc).
Django doesn’t handle it at all, largely because Python doesn’t either. Python (Guido?) has so far decided not to support timezones since although a reality of the world are “more political than rational, and there is no standard suitable for every application.”
The best solution for most is to not worry about it initially and rely on what Django provides by default in the settings.py file
TIME_ZONE = 'America/Los_Angeles' to help later on.
Given your situation pytz is the way to go (it’s already been mentioned). You can install it with
The server code to convert times stored in the database with the
America/Los_Angeles timezone to UTC looks like this:
>>> # Get a datetime from the database somehow and store into "x"
>>> x = ...
>>> # Create an instance of the Los_Angeles timezone
>>> la_tz = pytz.timezone(settings.TIME_ZONE)
>>> # Attach timezone information to the datetime from the database
>>> x_localized = la_tz.localize(x)
>>> # Finally, convert the localized time to UTC
>>> x_utc = x_localized.astimezone(pytz.utc)
If you send
x_utc down to an iPhone, iOS can do the same thing, etc. I hope that helps.
- Django logging – django.request logger and extra context
- Remove padding from matplotlib plotting
- How to import a Django project settings.py Python file from a sub-directory?
Not a Django expert here, but afaik Django has no magic, and I can’t even imagine any such magic that would work.
For example: you don’t always want to save times in UTC. In a calendar application, for example, you want to save the datetime in the local time that the calendar event happens. Which can be different both from the servers and the users time zone. So having code that automatically converts every selected datetime to the servers time zone would be a Very Bad Thing.
So yes, you will have to handle this yourself. I’d recommend to store the time zone for everything, and of course run the server in UTC, and let all the datetimes generated by the application use UTC, and then convert them to the users time zone when displaying. It’s not difficult, just annoying to remember. when it comes to datetimes that are inputted by the user, it’s dependant on the application if you should convert to UTC or not. I would as a general recommendation not convert to UTC but save in the users time zone, with the information of which time zone that is.
Yes, time zones is a big problem. I’ve written a couple of blog posts on the annoying issue, like here: http://regebro.wordpress.com/2007/12/18/python-and-time-zones-fighting-the-beast/
In the end you will have to take care of time zone issues yourself, because there is no real correct answer to most of the issues.
You could start by taking a look at the django-timezones application. It makes available a number of timezone-based model fields (and their corresponding form fields, and some decorators), which you could use to at least store different timezone values per user (if nothing else).
- How to output text from database with line breaks in a django template?
- Using Django's m2m_changed to modify what is being saved pre_add
Looking at the django-timezones application I found that it doesn’t support MySQL DBMS, since MySQL doesn’t store any timezone reference within datetimes.
Well, I think I manage to work around this by forking the Brosner library and modifying it to work transparently within your models.
There, I’m doing the same thing the django translation system do, so you can get user unique timezone conversion. There you should find a Field class and some datetime utils to always get datetimes converted to the user timezone. So everytime you make a request and do a query, everything will be timezoned.
- Django ManyToMany relation to 'self' without backward relations
- Why does Django South 1.0 use iteritems()?
You can see my answer explaining 2 ways without and with django-tz-detect to do automatically detect and apply the user’s current timezone rather than applying only one timezone set to TIME_ZONE in
- "Apps aren't loaded yet" when trying to run pytest-django
- Yuglify compressor can't find binary from package installed through npm