Использование
published_time = pytz.utc.localize(datetime.utcfromtimestamp(calendar.timegm(parsed_entry.published_parsed)))
Feedparser может анализировать широкий спектр форматов даты, вы можете найти их here.
Как вы можете видеть в feedparser/feedparser/datetimes/__init__.py
, встроенная функция от Feedparser _parse_date
выполняет следующие действия:
Parses a variety of date formats into a 9-tuple in GMT
Это означает, что в parsed_entry.published_parsed
у вас есть time.struct_time
объект в часовом поясе.
При преобразовании его в datetime
объекта с помощью
published_time = datetime.fromtimestamp(mktime(parsed_entry.published_parsed))
проблема заключается в том, что mktime
предполагает, что переданный кортеж в по местному времени, который не является, это GMT/UTC! Кроме того, вы не правильно локализуете объект datetime
в конце преобразования.
Необходимо заменить это преобразование следующим, помня, что Feedparser возвращает GMT struct_time
и локализует это с помощью часового пояса, который вам нравится (UTC для простоты).
- используется
calendar.timegm
, что дает количество секунд между эпохой и датой, переданной в качестве параметра, при условии, что переданный объект находится в UTC/GMT (мы знаем из Feedparser это)
- используется
utcfromtimestamp
для получения наивного объекта datetime
(который, как мы знаем, представляет дату-время в UTC, но Python в данный момент нет)
- С
pytz.utc.localize
вы правильно локализуете в UTC объект datetime
.
Пример:
import calendar
from datetime import datetime
import pytz
localized_dt = pytz.utc.localize(datetime.utcfromtimestamp(calendar.timegm(parsed_entry.published_parsed)))
Пока вы последовательны, это не имеет значения, если вы используете fromtimestamp
или utcfromtimestamp
. Если вы используете fromtimestamp
, вам нужно сообщить Python, что созданный вами объект datetime
имеет локальный часовой пояс. Предположим, вы находитесь в Европе/Берлин, это тоже хорошо:
pytz.timezone('Europe/Berlin').localize(datetime.fromtimestamp(calendar.timegm(parsed_entry.published_parsed)))
Были parsed_entry.published_parsed
также в местном часовом поясе, mktime
должен использоваться вместо calendar.timegm
.
В качестве альтернативы вы можете разобрать себя строку данных вы получите от Feedparser parsed_entry['published']
from dateutil import parser
localized_dt = parser.parse(parsed_entry['published'])
Вы можете проверить, что следующие возвращается True
:
parser.parse(parsed_entry['published']) == pytz.utc.localize(datetime.utcfromtimestamp(calendar.timegm(parsed_entry.published_parsed)))
Установка Django TIME_ZONE
фактически не потому что он используется только для целей визуализации или для автоматического преобразования наивных дат.
When USE_TZ is True, this is the default time zone that Django will use to display datetimes in templates and to interpret datetimes entered in forms.
Важно, чтобы всегда правильно использовать локализованные даты, независимо от того, какой часовой пояс используется. Пока они не в наивном формате, они будут надлежащим образом обработаны Django.
Вы заинтересованы в преобразовании часового пояса или вы сможете просто добавить час с датой.timedelta операция? – JwM
В конечном счете, я хотел бы иметь правильное время в UTC. Взятие часа сейчас (два часа в дневной сберегательный период) может быть способом. Хотя я еще не посмотрел на него. Мне было интересно, есть ли другой способ. Я пробовал, например, timezone.activate() и timezone.deactivate(), которые, похоже, правильно изменяли current_timezone, но это не помогло решить проблему. – apiljic
Вы можете сообщить дату и время или изменить часовой пояс, если это уже известно, но неправильно. –