34

我想将 Python 日期时间转换为 RFC 2822 日期时间。我试过这些方法无济于事:

>>> from email.Utils import formatdate
>>> import datetime
>>> formatdate(datetime.datetime.now())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/email    /utils.py", line 159, in formatdate
    now = time.gmtime(timeval)
TypeError: a float is required
4

5 回答 5

47

这是一些工作代码,为了清楚起见,将其分解为简单的部分:

>>> import datetime
>>> import time
>>> from email import utils
>>> nowdt = datetime.datetime.now()
>>> nowtuple = nowdt.timetuple()
>>> nowtimestamp = time.mktime(nowtuple)
>>> utils.formatdate(nowtimestamp)
'Tue, 10 Aug 2010 20:43:53 -0000'

说明:email.utils.formatdate想要一个时间戳——即自纪元以来具有秒数(及其分数)的浮点数。datetime实例不会直接为您提供时间戳——但是,它可以通过timetuple该方法为您提供时间元组,time.mktime然后当然可以从这样的元组中创建时间戳。

编辑:在 Python 3.3 和更新版本中,您可以在更少的步骤中执行相同的操作:

>>> import datetime
>>> from email import utils
>>> nowdt = datetime.datetime.now()
>>> utils.format_datetime(nowdt)
'Tue, 10 Feb 2020 10:06:53 -0000'

有关使用的详细信息,请参阅format_datetime 文档

于 2010-08-10T20:45:28.083 回答
27

如果您确实想要当前时间,只需formatdate不带参数调用:

>>> from email.utils import formatdate
>>> formatdate()
'Tue, 10 Aug 2010 20:40:23 -0000'

但是,如果你必须给它传递一个参数,你需要(自 1970 年 1 月 1 日time.time以来的秒数)的输出:

>>> import time
>>> formatdate(time.time())
'Tue, 10 Aug 2010 20:41:43 -0000'

FWIW,datetime.datetime.now()返回一个datetime对象,这不是formatdate预期的。

编辑添加:如果您已经有一个 datetime 对象,您可以为 formatdate 适当地格式化它:

>>> import datetime
>>> dt = datetime.datetime.now()
>>> formatdate(float(dt.strftime('%s')))
'Tue, 10 Aug 2010 20:46:16 -0000'

编辑:Alex Martelli 指出 strftime 的 '%s' 格式字符串可能无法跨平台移植。正如他自己所建议的那样,一个可能的替代方案是,

>>> formatdate(time.mktime(dt.timetuple()))
'Tue, 10 Aug 2010 20:46:16 -0000'
于 2010-08-10T20:43:44.643 回答
11

Python 3.3,除了其他评论者提到的方法外,还增加了一个format_datetime方法,更简洁:

>>> import datetime
>>> import email.utils
>>> dt = datetime.datetime.now()
>>> email.utils.format_datetime(dt)
'Thu, 09 Mar 2017 10:50:00 -0000'
于 2017-03-09T10:50:00.407 回答
1

使用 strftime 的简单方法。蟒蛇 2.7。注意:时区 = EST

>>> from datetime import datetime
>>> my_date = datetime.now()
>>> my_date.strftime('%a, %d %b %Y %H:%M:%S -0500')
'Wed, 22 Apr 2020 10:52:11 -0500'
于 2020-04-22T14:52:56.593 回答
0

如果您将其用于例如 HTTP 标头,并且想要GMT而不是-0000

  • 从 a datetime,使用format_datetime(强调我的):

    如果它是偏移量为零的感知时区,则usegmt可以设置为 True,在这种情况下,将使用字符串GMT而不是数字时区偏移量。

    >>> from datetime import datetime, timezone
    >>> from email.utils import format_datetime
    >>> format_datetime(datetime.now(timezone.utc), usegmt=True)
    'Wed, 27 Oct 2021 11:00:46 GMT'
    
  • 从时间戳,使用formatdate

    可选的usegmt是一个标志,当它True输出一个带有时区的日期字符串作为 ascii 字符串GMT,而不是一个数字 -0000......这仅适用于localtimeFalse

    >>> from email.utils import formatdate
    >>> from time import time
    >>> formatdate(time(), usegmt=True)
    'Wed, 27 Oct 2021 11:05:29 GMT'
    
于 2021-10-27T11:06:58.233 回答