电子邮件“日期”标题应该是发件人的当地时间还是 UTC?

Posted

技术标签:

【中文标题】电子邮件“日期”标题应该是发件人的当地时间还是 UTC?【英文标题】:Should email "Date" header be sender's local time or UTC? 【发布时间】:2012-05-16 06:26:06 【问题描述】:

我正在用 Python 编写一个基于 Web 的电子邮件客户端,但出现了一个问题,即发送时应将电子邮件的“日期”标头表示为哪个时区。

RFC 2822 在第 3.3 节中声明:

日期和时间应该表示当地时间。

这对我来说似乎模棱两可;问题是谁的当地时间?电子邮件服务器还是发件人?自然我会假设发件人(他可以在任何时区,并且可以在他们的帐户偏好中更改)。当我查看 Python 的 email.utils.formatdate 函数时,出现了进一步的困惑,该函数似乎只提供了两种选择:UTC 或本地时间(服务器的)。对我来说,似乎没有任何指定备用时区的选项,或者我错过了什么?

使用 time.mktime(senders_tz_aware_now_datetime.timetuple()) 将 timeval 传递给 formatdate 会产生一个 UTC 日期字符串,鉴于 RFC 上面所说的内容,这感觉是错误的。

那么“日期”应该是哪个时区,是否存在任何标准函数来创建适当的日期字符串?

【问题讨论】:

【参考方案1】:

只需使用 UTC,您就会更快乐。

当规范使用诸如应该这样的术语时,就会发生这种情况。我认为两者都应该被规范禁止,因为它们总是会产生不必要的复杂性。

使用 UTC 是完全有效的。

【讨论】:

那不行,我正在使用 timetuple 方法转换一个时区感知 datetime 对象,这意味着 is_dst 已经设置。它也没有回答我关于正确的日期时间表示是什么的问题。 改变主意了,走简单的路,晚上你就有时间喝啤酒了。 哈哈我喜欢你的风格。尽管如此,我还是想了解一下这通常是如何处理的,因为我认为它会对我从未听说过的一系列电子邮件客户端产生影响,更不用说拥有时间或资源进行测试了。跨度> 我怀疑您会看到客户无法应对 UTC。【参考方案2】:

如果您想遵守 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。

【讨论】:

谢谢,当然这是我们最初认为可以解决问题的方法。不幸的是,你的回答提出了一个让我很难过的问题:什么是“正确的时区”?设置localtime=True 返回服务器的时区,而不是发送者的时区。因此我的问题是,它应该是服务器的本地时区还是发件人的本地时区?人们会假设发件人的时区是正确的做法。但是在这种情况下,我看不到 formatdate 提供了执行此操作的必要功能。 发件人所在的时区并不重要,只要您生成一个一致的时间戳来表示电子邮件的发送时间即可。由接收方的客户来正确解释它。这就是为什么@Sorin 建议使用 UTC,这是最简单的方法。 我同意这无关紧要,但令我困扰的是 RFC 说它应该显示为当地时间。 您如何知道客户的时区?如果昨天从伦敦注册的客户一天后在日本怎么办?服务器端的本地时间只能表示本地服务器时间,而不是本地客户端时间。如果邮件发送到 10 个时区的 10 个客户,你会使用哪个? (使用 UTC +1,即使您忘记更新时区数据库,您的程序也不会中断)【参考方案3】:

当谷歌搜索“电子邮件客户端本地时间”时,这是一个最重要的结果;不幸的是,这两个答案和随附的 cmets 几乎没有解决 python 实现,并且完全无法与主题行对话(这是谷歌响应的内容)。

RFC 是明确的,因为它很明显:“^Date:”标头在写入时是本地的。邮件客户端通常会写入“^Date:”标头(在我处理过的许多实现中)。对于大多数(配置合理的)客户端,这将是客户端操作系统报告的本地时间。

在 webmail 的情况下,本地时间可以由用户代理提供(通常依次从操作系统获取本地时间)。更典型的是,它是由用户在 Web 应用程序中设置的 (a la gmail)。

重要的是,如果您“遵循 RFC”(对于网络协议来说可能是一个好主意),RECEIVING 客户端上的结果行为通常会显示发件人看到的邮件发送日期。这就是 RFC 中“应该”的全部意义。在试图弄清楚同事什么时间发送电子邮件时,我不想看到 UTC;我想要他们的当地时间。这样,我可以一步计算出时差(他们的本地时间到我的时间),而不是两个(他们的本地时间到 UTC 到我的本地时间)。我还可以立即获得有关他们通信背景的线索(是晚上吗?工作时间?等等)。

【讨论】:

以上是关于电子邮件“日期”标题应该是发件人的当地时间还是 UTC?的主要内容,如果未能解决你的问题,请参考以下文章

重新发送 MIME 电子邮件中的标头

作为收件人,是不是可以检测电子邮件是通过 Gmail“计划发送”还是“发送”发送的?

UTC 时间、时区、夏令时和夏令时切换日期

邮件重复数据删除多个用户

带有 html 正文的 Powershell 电子邮件发件人 (htmlbody.Replace)

使用 MailMessage 向多个收件人发送电子邮件?