I want to use timezones according to the babel locale. How can I achieve this? The specific situation I have is the goal of displaying the date and time of an article and a humanized and localized way eg:
Yesterday
13:21
or if the Swedish language parameter is set it will display
Igår
13:21
And if the date wasn’t yesterday or today, it will print the date and 24 hrs time. I think I succeeded with everything except handling the timezone:
from webapp2_extras import i18n from webapp2_extras.i18n import lazy_gettext as _ import datetime from datetime import date, datetime, time from babel.dates import format_date, format_datetime, format_time from babel.numbers import format_number, format_decimal, format_percent def datetimeformat_jinja(value, format='%H:%M / %d-%m-%Y', locale='en'): now= datetime.now() info = None if datetime.date(value) == datetime.date(now): info= _('Today') elif (now - value).days < 2: info= _('Yesterday') else: month = value.month if month == 1: info = str(value.day)+' '+_('Jan') elif month == 2: info = str(value.day)+' '+_('Feb') elif month == 3: info = str(value.day)+' '+_('Mar') elif month == 4: info = str(value.day)+' '+_('April') elif month == 5: info = str(value.day)+' '+_('May') elif month == 6: info = str(value.day)+' '+_('June') elif month == 7: info = str(value.day)+' '+_('July') elif month == 8: info = str(value.day)+' '+_('Aug') elif month == 9: info = str(value.day)+' '+_('Sep') elif month == 10: info = str(value.day)+' '+_('Oct') elif month == 11: info = str(value.day)+' '+_('Nov') else: info = str(value.day)+' '+_('Dec') return info+'<br>'+format_time(value, 'H:mm', locale=locale)
The above code localizes and humanizes the output:
I can also switch languages to eg Brazilian Portuguese:
Where “Hoje” means “today” so the filter appears to work.
Could you please tell me how I can enable my code to also allow timezones? I use babel for localization and Jinja2 for rendering. Should the timezone be the timezone of the article or the timezone of the viewer? For instance, a Brazilian user in Brazil posts a message and a Swedish viewer in Sweden views the message. Which timezone should then be used?
The way I can try to handle timezones is by importing the pytz library like the documentation states and using I timezone object. I can pass the timezone parameter via the template code but how to know the timezone parameter, from the article or from the locale? In this case the locale and the timezone will be different since it’s for India and locale is English and timezone India:
{{ article.modified|datetimeformat_jinja(locale='en') }}
Then I can also pass I timezone parameter like this
{{ article.modified|datetimeformat_jinja(locale='en') }}
filter:
def datetimeformat_jinja(value, format='%H:%M / %d-%m-%Y', locale='en', tzinfo=timezone('India')): now= datetime.now() info = None if datetime.date(value) == datetime.date(now): info= _('Today') elif (now - value).days < 2: info= _('Yesterday') else: month = value.month if month == 1: info = str(value.day)+' '+_('Jan') elif month == 2: info = str(value.day)+' '+_('Feb') elif month == 3: info = str(value.day)+' '+_('Mar') elif month == 4: info = str(value.day)+' '+_('April') elif month == 5: info = str(value.day)+' '+_('May') elif month == 6: info = str(value.day)+' '+_('June') elif month == 7: info = str(value.day)+' '+_('July') elif month == 8: info = str(value.day)+' '+_('Aug') elif month == 9: info = str(value.day)+' '+_('Sep') elif month == 10: info = str(value.day)+' '+_('Oct') elif month == 11: info = str(value.day)+' '+_('Nov') else: info = str(value.day)+' '+_('Dec') return info+'<br>'+format_time(value, 'H:mm', tzinfo=tzinfo, locale=locale)
So at least it seems I can localize one timezone but I’m wondering how to make it dynamic.
Advertisement
Answer
Should the timezone be the timezone of the article or the timezone of the viewer? For instance, a Brazilian user in Brazil posts a message and a Swedish viewer in Sweden views the message. Which timezone should then be used?
I would always display time as “wall clock time” which means use the timezone your viewer would see on a regular clock on his desk. However that’s up to you.
I can pass the timezone parameter via the template code but how to know the timezone parameter, from the article or from the locale? In this case the locale and the timezone will be different since it’s for India and locale is English and timezone India:
The ugly truth is that timezones and locales are two different beasts with only a very loose connection between them. For example an Indian in Sweden still wants to read English (Hindi, …) but in a Swedish timezone.
Of course you can hard-code it for specific uses but a more sensible thing would be to decouple locale from timezone and let the user control the timezone setting.
As for your code you probably need to switch from naive datetimes to tz-aware datetimes.