2016-01-15 2 views
3

Я знаю, что это было задано раньше, и я все еще держу свои волосы, пытаясь понять это. Я пробовал pytz, dateutil, а теперь flask_moment. Все еще возникают проблемы с преобразованием таблицы datetime MySQL, которая является UTC, для отображения в шаблоне jinja2 в качестве локального времени, в частности UTC - 05:00 (EST).UTC в местный часовой пояс в фляге/шаблон jinja

Мой jinja2 цикл выглядит следующим образом:

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

Я новичок в Python/колба/дзиндзя, так легко идти на меня, пожалуйста. Документация довольно запутанная для нуба, такого как я. Может кто-нибудь, пожалуйста, проведет меня через получение моей таблицы MySQL для отображения времени в локальном часовом поясе?

Я чувствую, что это близко, но с этим возникают ошибки. В INIT .py, я имел:

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 %} 

Но это дает мне "ValueError: Час должен быть в 0..23" От линии:

local_dt.replace(hour=local_dt.hour + int(local_dt.utcoffset().total_seconds()/3600)) 

Заранее спасибо!

ответ

1

Локализация не изменит часовой пояс, а скорее добавит информацию о часовом поясе к наивному объекту datetime. Вы говорите, что ваше время datetime исходит от SQL и находится в UTC, но является ли объект datetime осведомленным в часовом поясе? Если value является DateTime объекта, который знает это UTC, а не наивное объект DateTime, вы должны изменить часовой пояс, как этого

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 наивного объект DateTime и вы можете сделать это часовым поясом (как UTC) 1-го, а затем получить локализованное datetime, как это.

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) 

Существует несколько способов проверить, является ли ваш объект datetime наивным или нет. Например, если он знает о своем часовом поясе, то value.tzname() вернет имя часового пояса, иначе оно не вернет его.

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

Naive datetime object: datetime.datetime(2016, 1, 1, 9, 28, 26, 149703)

+0

Спасибо Schechter, но кажется, что даже после вашего второго предложения, что я все еще получаю ValueError: astimezone() нельзя применить к наивному дате. Ближе, но все еще не совсем работаю для меня. –

+0

Yeah Schechter, выглядит как строка, которая читает 'tz_aware_dt = utc.localize (value)' должна быть: 'tz_aware_dt = utc.localize (значение) .astimezone (pytz.utc)', чтобы на самом деле сделать это известно –

+0

Спасибо, что указали, что out @RyanGreever. Я думаю, что я оставил «ценность», где должно было быть tz_aware_dt. Я отредактировал ответ, чтобы отразить изменения. – Schechter

2

Это то, что в конечном итоге работает для меня, в данном конкретном случае, и я до сих пор не уверен, если это будет давать неверную информацию в течение летнего времени, но мы будем видеть.

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 %} 

Если есть способ улучшить это, я открыт для предложений, но до сих пор, это единственный способ, который я нашел, что работает.

+0

Спасибо за это. Это отлично работает для меня! – afed

+0

Это то, что я искал. Благодарю. – twk

Смежные вопросы