Должен ли почтовый заголовок "Дата" отправляться по местному времени или по UTC?
Я пишу веб-почтовый клиент на Python и возникает вопрос, в какой временной зоне заголовок "Дата" сообщения электронной почты должен быть представлен как при отправке.
RFC 2822 говорится в разделе 3.3, что:
Дата и время суток ДОЛЖНЫ выражать местное время.
Это кажется мне двусмысленным; вопрос - местное время, кто? Сервер электронной почты или отправитель? Естественно, я предполагаю отправителя (который может находиться в любом часовом поясе и может быть изменен в настройках учетной записи). Дальнейшее замешательство возникло, когда я посмотрел Python email.utils.formatdate, который, кажется, предлагает только две альтернативы: UTC или местное время (на сервере). Мне кажется, что нет возможности указать альтернативный часовой пояс, или я что-то упускаю?
Передача timeval для форматирования с использованием time.mktime(senders_tz_aware_now_datetime.timetuple())
приводит к строке дат UTC, которая кажется неправильной, учитывая то, что RFC говорит выше.
Итак, какой временной зоной должен быть "Дата", и существует ли какая-либо стандартная функция для создания соответствующей строки даты?
Ответы
Ответ 1
Если вы хотите придерживаться RFC, пройдите localtime=True
, который возвращает строку даты с местным временем и правильным часовым поясом (при условии, что вы правильно настроили его).
>>> email.utils.formatdate(localtime=True)
'Mon, 07 May 2012 12:09:16 -0700'
Без localtime=True
вы получаете строку даты, представляющую время UTC:
>>> email.utils.formatdate()
'Mon, 07 May 2012 19:08:55 -0000'
-0000
, по-видимому, указывает UTC, хотя RFC специально рекомендует использовать +0000
. Не уверен, что это ошибка в email.utils.
Здесь соответствующая документация python:
Дополнительное localtime - это флаг, который, когда True, интерпретирует timeval и возвращает дату относительно локального часового пояса вместо UTC, должным образом учитывает время летнего времени. Значение по умолчанию - False означает, что используется UTC.
Ответ 2
Просто используйте UTC, и вы будете счастливее.
Это то, что происходит, когда спецификации используют такие термины, как СЛЕДУЕТ. Я думаю, что оба СЛЕДУЮТ могут быть запрещены спецификациями, потому что они всегда создают ненужную сложность.
Использование UTC абсолютно корректно.
Ответ 3
Это выглядит как результат, когда googling "местное время клиента электронной почты"; к сожалению, два ответа и сопроводительные комментарии едва затрагивают реализацию python и не позволяют полностью поговорить с темой темы (что и является причиной ответа Google).
RFC однозначен, потому что он очевиден: заголовок "^ Date:" является локальным в момент его написания. Почтовый клиент обычно записывает заголовок "^ Date:" (в любой из многих реализаций, которые я рассматривал). Для большинства (настроенных) клиентов это будет местное время, о котором сообщает клиентская ОС.
В случае веб-почты местное время может быть предоставлено агентом пользователя (который, в свою очередь, получает локальное время от ОС). Более типично он будет установлен пользователем в веб-приложении (a la gmail).
Важно отметить, что если вы "следуете RFC" (вероятно, хорошая идея для сетевого протокола), результатом поведения клиентов RECEIVING будет, как правило, дата, когда почта была отправлена, как видно отправителю. В этом весь смысл "СЛЕДУЕТ" в RFC. Я не хочу видеть UTC, пытаясь выяснить, в какое время коллега отправил электронное письмо; Я хочу их местное время. Таким образом, я могу понять разницу во времени на один шаг (их местное время для моего), а не два (их местное время до UTC до моего локального времени). Я также получаю немедленные подсказки относительно контекста их сообщений (было ли это ночное рабочее время? И т.д.).