Конвертировать Python datetime в rfc 2822

Я хочу преобразовать дату и время 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

5 ответов

Решение

Вот некоторый рабочий код, разбитый на простые части для ясности:

>>> 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 Конечно, затем можно сделать метку времени из такого кортежа.

Если вы действительно хотите текущее время, просто позвоните formatdate без аргументов:

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

Но, если вы должны передать ему аргумент, вы хотите вывод time.time (количество секунд с 01.01.1970):

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

Отредактировано: Алекс Мартелли отметил, что строка формата '%s' для strftime может не переноситься на разные платформы. Возможная альтернатива будет, как он сам предложил,

>>> formatdate(time.mktime(dt.timetuple()))
'Tue, 10 Aug 2010 20:46:16 -0000'

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'

Простой метод с использованием strftime. Python 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'

Если вы используете это, например, для HTTP-заголовка и хотите, а не:

  • Из datetime, использовать format_datetime:

    Если это известный часовой пояс со смещением нуля, то для usegmt может быть установлено значение, и в этом случае вместо числового смещения часового пояса используется строка.

            >>> 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... Это относится только тогда , когда LocalTime является False.

            >>> from email.utils import formatdate
    >>> from time import time
    >>> formatdate(time(), usegmt=True)
    'Wed, 27 Oct 2021 11:05:29 GMT'
    
Другие вопросы по тегам