UTC到烧瓶/ jinja模板中的本地时区

时间:2016-01-15 03:26:01

标签: python flask jinja2

我知道以前曾经问过这个问题,而且我还在试着想出这个问题。我已经尝试过pytz,dateutil和现在的flask_moment。转换MySQL表日期时间(UTC)仍然无法在jinja2模板中显示为本地时间,特别是UTC - 05:00(EST)。

我的jinja2 for循环看起来像这样:

import numpy as np

elements = np.linspace(0., 1., 3270)

我是python / flask / jinja的新手,所以请放轻松。对于像我这样的菜鸟来说,文档很混乱。有人可以请我通过获取我的MySQL表来显示当地时区的时间吗?

我觉得这很接近,但却犯了错误。在 init .py中,我有:

{% for data in items %}
    ...
   <td>{{data.loggedInBy}}</td>
   <td>{{data.timeIn.strftime('%I:%M %p')}}</td>
    ...
{% endfor %}

但是这给了我&#34; ValueError:小时必须在0..23&#34; 从行:

from pytz import timezone

def datetimefilter(value, format='%I:%M %p'):
    tz = timezone('US/Eastern')
    dt = value
    local_dt = tz.localize(dt)
    local_dt.replace(hour=local_dt.hour + int(local_dt.utcoffset().total_seconds() / 3600))
    return local_dt.strftime(format)

flask_app.jinja_env.filters['datetimefilter'] = datetimefilter

jinja template had:

{% for data in items %}
...
<td>{{data.loggedInBy}}</td>
<td>{{data.timeIn | datetimefilter }}</td>
...
{% endfor %}

提前致谢!

3 个答案:

答案 0 :(得分:5)

在这种特殊情况下,这最终为我工作了,我仍然不确定它是否会在DST期间提供不正确的信息,但我们会看到。

import pytz
from pytz import timezone
import tzlocal 

def datetimefilter(value, format="%I:%M %p"):
    tz = pytz.timezone('US/Eastern') # timezone you want to convert to from UTC
    utc = pytz.timezone('UTC')  
    value = utc.localize(value, is_dst=None).astimezone(pytz.utc)
    local_dt = value.astimezone(tz)
    return local_dt.strftime(format)

flask_app.jinja_env.filters['datetimefilter'] = datetimefilter

然后我的jinja2模板看起来像:

{% for data in items %}
...
<td>{{data.loggedInBy}}</td>
<td>{{data.timeIn | datetimefilter }}</td>
...
{% endfor %}

如果有任何改进的方法,我愿意接受建议,但到目前为止,这是我发现有效的唯一方法。

答案 1 :(得分:1)

Localize不会改变时区,而是将时区信息添加到天真的日期时间对象。您说您的日期时间来自SQL并且是UTC,但是是时区感知日期时间对象吗?如果value是一个日期时间对象,它知道它是UTC而不是一个天真的日期时间对象,你应该像这样改变时区

tz = pytz.timezone('US/Eastern')  # timezone you want to convert to from UTC
local_dt = value.astimezone(tz)
return local_dt.strftime(format)

如果您收到错误
ValueError: astimezone() cannot be applied to a naive datetime
那么你的value是一个天真的日期时间对象,你可以让它知道时区(如UTC)1,然后得到你这样的本地化日期时间。

tz = pytz.timezone('US/Eastern')
utc = pytz.timezone('UTC')
tz_aware_dt = utc.localize(value)
local_dt = tz_aware_dt.astimezone(tz)
return local_dt.strftime(format)

您可以通过多种方式查看日期时间对象是否天真。例如,如果它知道它的时区value.tzname()将返回时区的名称,否则它将不返回任何时区。

  

时区感知:datetime.datetime(2016, 1, 1, 4, 28, 26, 149703, tzinfo=<DstTzInfo 'US/Eastern' EST-1 day, 19:00:00 STD>)

     

天真的日期时间对象:datetime.datetime(2016, 1, 1, 9, 28, 26, 149703)

答案 2 :(得分:0)

在这种情况下,最好使用

Flask-Moment。有关详细说明,请参见链接。