I have users in many timezones and I let them set their preferred display timezone in their user profile as a string (validated aginst the pytz valid timezones).
This is a filter that takes a datetime as input and as an argument the user to figure out the timezone from.
It requires that there is a user profile model with a 'timezone' field. If a specific user does not have a user profile we fall back on the settings.TIME_ZONE. If the datetime is naieve then we again fallback on the settings.TIME_ZONE.
It requires the 'pytz' module: http://pytz.sourceforge.net/
Use: {{ post.created|user_tz:user|date:"D, M j, Y H:i" }}
The example is assuming a context in which the 'user' variable refers to a User object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | import pytz
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
@register.filter()
def user_tz(value, user):
"""Expects a datetime as the value. Expects a User object as the arg.
Looks up the 'timezone' value in the user's profile, and converts
the given datetime in to one in the user's timezone.
NOTE: This assumes that you have the 'pytz' module
(pytz.sourceforge.net) and that the user profile has a field
called 'timezone' that is a character string and that the timezone
thus specified is a valid timezone supported by pytz.
"""
tz = settings.TIME_ZONE
if isinstance(user, User):
try:
tz = user.get_profile().timezone
except ObjectDoesNotExist:
pass
try:
result = value.astimezone(pytz.timezone(tz))
except ValueError:
# Hm.. the datetime was stored 'naieve' ie: without timezone info.
# we assume the timezone in 'settings' for all naieve objects.
#
result = value.replace(tzinfo=pytz.timezone(settings.TIME_ZONE)).astimezone(pytz.timezone(tz))
return result
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 11 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
- Help text hyperlinks by sa2812 1 year, 7 months ago
Comments
i think a cleaner solution would be to pass the timezone as a parameter and not a user instance. the drawback would be more writing-work in your templates...
just my 2cents
#
When using this filter I noticed that it was not converting time properly with naive dates between 'America/Chicago' and America/Sao_Paulo. It was adding an extra hour. To add the timezone to a naive date you should do something like this for line 28 (result = val..):
value = pytz.timezone(settings.TIME_ZONE).localize(value) result = value.astimezone(pytz.timezone(tz))
#
Please login first before commenting.