8

我正在尝试使用 python 脚本解析电子邮件的日期时间。

当我打开邮件详细信息时,邮件中的日期值如下所示...

from:    abcd@xyz.com
to:      def@xyz.com
date:    Tue, Aug 28, 2012 at 1:19 PM
subject: Subject of that mail

我正在使用类似的代码

mail = email.message_from_string(str1)
#to = re.sub('</br>','',mail["To"])
to = parseaddr(mail.get('To'))[1]
sender = parseaddr(mail.get('From'))[1]
cc_is = parseaddr(mail.get('Cc'))[1]
date = mail["Date"]
print date

使用 python 解析的相同邮件日期时间的输出如下所示,带有时间偏移。

Tue, 28 Aug 2012 02:49:13 -0500

我真正希望的地方

Tue, Aug 28, 2012 at 1:19 PM

我对这两个价值观的关系感到很困惑。任何人都可以帮我弄清楚我需要同时了解邮件详细信息。

4

3 回答 3

24

在 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
于 2012-08-28T13:13:19.830 回答
8

你可以只使用 stdlib 来做到这一点:

>>> from email.utils import parsedate_tz, mktime_tz, formatdate
>>> ts = mktime_tz(parsedate_tz('Tue, 28 Aug 2012 02:49:13 -0500'))
>>> formatdate(ts, localtime=True) # assuming Asia/Kolkata is the local timezone
'Tue, 28 Aug 2012 13:19:13 +0530'

如果你想使用PM几个小时的格式:

>>> from datetime import datetime
>>> datetime.fromtimestamp(ts).strftime('%a, %b %d, %Y at %I:%M %p')
'Tue, Aug 28, 2012 at 01:19 PM'
于 2014-04-17T00:07:49.900 回答
2

可以选择以下代码

start = f.find('date:') + 5  # +5 is to exclude 'date'+':' i.e.(4+1=5)
end = f.find('subject:', start) # parse from date to subject 
date_time = f[start:end]
print date_time #it will print "Tue, Aug 28, 2012 at 1:19 PM"
于 2018-07-31T11:35:51.263 回答