Automatic user’s timezone determination with JavaScript and django-timezones 3
There is a nice solution to manage timezones: django-timezones. It allows you to store a user’s timezone in his profile and show time in his timezone. How do we determine a user timezone by not asking him to fill in a profile manually? One of the ways is a client script that can get timezone offset in minutes. Lets use it to automatically set timezone on page load using ajax request:
$(document).ready(function(){ $.post("/ajax_set_timezone/", {timezone_offset: new Date().getTimezoneOffset()}); });
Now there is problem: converting timezone offset to timezone on server side. We can iterate over all timezones and find first, which fits in a specified time offset. It will be a wrong timezone (in most cases), but correct time offset (which is more important for us):
from django import http from models import UserProfile import pytz import datetime def ajax_set_timezone(request): if not request.user.is_authenticated(): return http.HttpResponseBadRequest() # Load or create user profile. try: profile = request.user.get_profile() except UserProfile.DoesNotExist: profile = request.user.userprofile_set.create() if request.method == "POST": if "timezone_offset" in request.POST: # Create timezone offset in required format. # Javascript sends offset in minutes. -120 = GMT+0200 try: minutes = int(request.POST["timezone_offset"]) except (ValueError, TypeError): return http.HttpResponseBadRequest() if minutes < 0: minutes = -minutes minus = True else: minus = False min = minutes % 60 hours = (minutes - min) / 60 offset = "%s%02d%02d" % (minus and "+" or "-", hours, min) # Check if timezone not changed. now = datetime.datetime.now(pytz.timezone(profile.timezone)) if now.strftime("%z") == offset: return http.HttpResponse("ok") # This is only method I found to determine timezone by offset. for tz in pytz.common_timezones: now = datetime.datetime.now(pytz.timezone(tz)) if now.strftime("%z") == offset: profile.timezone = tz profile.save() return http.HttpResponse("ok") return http.HttpResponseBadRequest()
After successful execution this view will set timezone to user’s profile.
In this example user profile model should look like:
from django.db import models from django.contrib.auth.models import User from timezones.fields import TimeZoneField class UserProfile(models.Model): user = models.ForeignKey(User, unique=True) timezone = TimeZoneField()
To make user.get_profile() working we also need to set profile module in django settings file:
AUTH_PROFILE_MODULE = "app_name.UserProfile"

The layout for your site is a bit off in Opera. Even So I like your site. I may have to install a “normal” browser just to enjoy it.
Very nice Nazar. Thanks for this helpful tip.
How do you get the admin panels to display a DateTime field with the date and time in the user’s timezone?
For example:
class Article(models.Model):
publish_datetime = models.DateTimeField(
_(”Publish at”),
default=datetime.now,
blank=True
)
and then in the back end, will the date time be stored in a common timezone so that, in this case, articles will be ordered correctly?
I notice the datetime field in the admin also doesn’t mention the timezone. Maybe the admin field needs to be modified to include a timezone selector?
Try dig django-timezones documentation. There is LocalizedDateTimeField field.
To store UTC time and showing user’s time I used custom forms and “timezones.utils.adjust_datetime_to_timezone” function in django-timezones app. So when user saves some date I converted it to UTC and vice versa.