在 GMail 中查看电子邮件时,在显示电子邮件的发送日期和时间时使用您的本地时区。“Tue, 28 Aug 2012 02:49:13 -0500” 被解析,然后更新到您的本地时区,并以特定于 GMail 的方式格式化。
解析和格式化stdlib方式
该email.utils
模块包含一个专门处理带有时区偏移的电子邮件标头的parsedate_tz()
功能。
它返回一个与 兼容的元组time.struct_time
,但添加了时区偏移量。一个附加mktime_tz()
函数将该元组转换为偏移值(自 UNIX 纪元以来的时间,以秒为单位)。然后可以datetime.datetime()
轻松地将这个值转换为类型对象。
同一模块还具有将 UNIX 纪元时间戳转换为与电子邮件兼容的日期字符串的formatdate()
功能:
>>> from email.utils import parsedate_tz, mktime_tz, formatdate
>>> import time
>>> date = 'Tue, 28 Aug 2012 02:49:13 -0500'
>>> tt = parsedate_tz(date)
>>> timestamp = mktime_tz(tt)
>>> print formatdate(timestamp)
Tue, 28 Aug 2012 07:49:13 -0000
现在我们有了一个适合外发电子邮件的 UTC 格式日期。要将其打印为我的本地时区(由我的计算机确定),您需要将localtime
标志设置为True
:
>>> print formatdate(timestamp, True)
Tue, 28 Aug 2012 08:49:13 +0100
使用更好的工具进行解析和格式化
请注意,当我们尝试处理时区时,事情变得越来越棘手,并且该formatdate()
功能没有为您提供任何不同格式的选项(如 GMail 所做的那样),也不允许您选择不同的时区来使用。
进入外部python-dateutil
模块;它有一个解析函数,几乎可以处理任何事情,并正确支持时区
>>> import dateutil.parser
>>> dt = dateutil.parser.parse(date)
>>> dt
datetime.datetime(2012, 8, 28, 2, 49, 13, tzinfo=tzoffset(None, -18000))
该parse()
函数返回一个datetime.datetime()
实例,这使得格式化变得更加容易。现在我们可以使用该.strftime()
函数像您的电子邮件客户端一样输出它:
>>> print dt.strftime('%a, %b %d, %Y at %I:%M %p')
Tue, Aug 28, 2012 at 02:49 AM
当然,那仍然是当地时区。要将其转换为您的时区,请使用带有新对象的.astimezone()
方法。tzone
这个python-dateutil
包裹对我们有一些方便。
以下是在本地时区(到您的机器)打印它的方法:
>>> import dateutil.tz
>>> print dt.astimezone(dateutil.tz.tzlocal()).strftime('%a, %b %d, %Y at %I:%M %p')
Tue, Aug 28, 2012 at 09:49 AM
或改用特定时区:
>>> print dt.astimezone(dateutil.tz.tzstr('Asia/Kolkata')).strftime('%a, %b %d, %Y at %I:%M %p')
Tue, Aug 28, 2012 at 07:49 AM