Convert Python datetime to rfc 2822

Here's some working code, broken down into simple pieces just for clarity:

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

Explanation: email.utils.formatdate wants a timestamp -- i.e., a float with seconds (and fraction thereof) since the epoch. A datetime instance doesn't give you a timestamp directly -- but, it can give you a time-tuple with the timetuple method, and time.mktime of course can then make a timestamp from such a tuple.

EDIT: In Python 3.3 and newer you can do the same in less steps:

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

See format_datetime docs for details on usage.


If you indeed want the current time, just call formatdate with no arguments:

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

But, if you must pass it an argument, you want the output of time.time (a number of seconds since 01/01/1970):

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

FWIW, datetime.datetime.now() returns a datetime object, which is not what formatdate expects.

Edited to add: if you already have a datetime object, you can format it appropriately for formatdate:

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

Edited: Alex Martelli noted that the '%s' format string for strftime may not be portable across platforms. A possible alternative would be, as he himself suggested,

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