【问题标题】:Convert Python datetime to rfc 2822将 Python 日期时间转换为 rfc 2822
【发布时间】:2011-03-28 01:26:51
【问题描述】:

我想将 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

【问题讨论】:

    标签: python datetime rfc2822


    【解决方案1】:

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

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

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

    >>> 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'
    

    【讨论】:

    • 有趣——'%s' 格式到strftime 似乎没有记录,因此是“碰巧在某些平台上工作”(但不是在所有平台上)之一——除非你有文档显示它跨平台工作吗?
    • 实际上,这是 Unix "date" 命令用于输出基于纪元的时间的格式字符串,我不假思索地使用它并且它有效:) 我会检查并回复你(或改变我的答案)。
    • 好吧,docs.python.org/library/… 声明“支持的完整格式代码集因平台而异,因为 Python 调用平台 C 库的 strftime() 函数,并且平台变化很常见。”而且,在 Linux 上, man 3 strftime 将 '%s' 列为可能的格式值。所以我想你是对的,它可能不是便携式的。谢谢:)
    • 它不可移植 - 在 Windows (Python 2.7) 上'%s'不起作用:ValueError: Invalid format string
    • @theta 你读过我的完整答案了吗?最后一段和代码块正好解决了这个问题。
    【解决方案2】:

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

    >>> 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_datetimedocs

    【讨论】:

    • 为什么不直接使用 time.time() ?
    • 在 3.3 版中,datetime 有了timestamp 方法,使这个过程更快。
    • 在 Python 3.3 email.utils 中得到了方法format_datetime(),它简化了这个过程:docs.python.org/3/library/…
    【解决方案3】:

    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'
    

    【讨论】:

      【解决方案4】:

      使用 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'
      

      【讨论】:

        【解决方案5】:

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

        • 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'
          

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-10-27
          • 1970-01-01
          • 2015-12-04
          • 1970-01-01
          • 1970-01-01
          • 2012-12-08
          • 1970-01-01
          • 2012-01-28
          相关资源
          最近更新 更多