如何在我的jinja过滤器中使用babel启用时区?
我想根据babel的语言设置来使用时区。请问我该怎么做?具体来说,我的目标是以一种人性化和本地化的方式显示文章的日期和时间,比如:
昨天
13:21
或者如果设置的是瑞典语参数,它会显示:
Igår
13:21
如果日期不是昨天或今天,它就会打印出日期和24小时制的时间。我觉得我在其他方面都做得不错,除了处理时区:
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)
上面的代码可以本地化和人性化输出:
我还可以切换语言,比如巴西葡萄牙语:
其中“Hoje”意思是“今天”,所以这个过滤器看起来是有效的。
你能告诉我怎么让我的代码也支持时区吗?我使用babel进行本地化,使用Jinja2进行渲染。时区应该是文章的时区还是查看者的时区?比如,一个在巴西的用户发布了一条消息,而一个在瑞典的查看者查看了这条消息。那应该用哪个时区呢?
我可以尝试通过导入pytz库来处理时区,就像文档中说的那样,并使用一个时区对象。我可以通过模板代码传递时区参数,但怎么知道这个时区参数是来自文章还是来自语言环境呢?在这种情况下,语言环境和时区会不同,因为它是印度的,而语言环境是英语,时区是印度:
{{ article.modified|datetimeformat_jinja(locale='en') }}
然后我也可以这样传递时区参数:
{{ article.modified|datetimeformat_jinja(locale='en') }}
过滤器:
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)
所以至少看起来我可以本地化一个时区,但我在想怎么让它变得动态。
1 个回答
时间应该显示为文章的时区还是观看者的时区呢?比如说,一个在巴西的用户发了一条消息,而一个在瑞典的用户查看了这条消息。那么应该用哪个时区呢?
我会始终显示为“墙上时钟时间”,也就是说,使用观看者在桌子上看到的普通时钟的时区。不过,这个决定还是要看你自己。
我可以通过模板代码传递时区参数,但怎么知道这个时区参数是来自文章还是来自地区呢?在这种情况下,地区和时区会不同,因为这是关于印度的,而地区是英语,时区是印度的:
实际上,时区和地区是两回事,它们之间的联系非常松散。比如说,一个在瑞典的印度人仍然想用英语(或者印地语等)阅读,但他希望看到的是瑞典的时区。
当然,你可以为特定的用途硬编码时区,但更明智的做法是将地区和时区分开,让用户自己控制时区设置。
至于你的代码,你可能需要把简单的日期时间切换到支持时区的日期时间。