That is good you are storing everything in UTC
. Now you don't need to store the user timezone in database what you can do is that on login page you can calculate the user offset from UTC
and store in session vi ajax. Here is the simple script you can include in your login page template:
<script>
$(document).ready(function(){
var visitortime = new Date();
var visitortimezone = - visitortime.getTimezoneOffset()/60;
$.ajax({
type: "POST",
url: "{% url 'update_timezone' %}",
data: {'time_zone': visitortimezone, 'csrfmiddlewaretoken': '{{csrf_token}}'},
dataType: "text"
});
});
</script>
Add this url in your root urls.py:
url(r'^update_timezone/$',
'MySite.views.update_timezone',
name='update_timezone'),
Add this view:
def update_timezone(request):
time_zone = request.POST.get('time_zone', 0)
if time_zone:
request.session['user_timezone_offset'] = float(time_zone)*60*60
return HttpResponse(
simplejson.dumps({}), mimetype='application/javascript')
Now you have user timezone offset in session. Now comes the part for calculation. You need these two simple helper functions:
from datetime import timedelta
def add_user_offset(dt, offset):
if offset:
dt = dt + timedelta(seconds=offset)
return dt
def subtract_user_offset(dt, offset):
if offset:
dt = dt - timedelta(seconds=offset)
return dt
Ok if you want to show the user time according to the his/her timezone you would do:
created = add_user_offset(obj.created, request.session.get('user_timezone_offset'))
If you have datetime or date coming from the form and you want to validate it e.g. the date chosen should not be less than current date you would do:
from django.utils import timezone
d = request.POST['date']
d_normalize = subtract_user_offset(d, request.session.get('user_timezone_offset'))
if d_normalize < timezone.now():
raise Exception, 'Date must be in future'
The benefit of this approach is that you don't need to ask users to specify their timezones. We are doing everything automatically on our side.