Perl programmer for hire: download my resume (PDF).
John Bokma's Hacking & Hiking

RFC #822 and RFC #3339 dates in Python

October 9, 2019

When adding a JSON feed and an RSS feed to tumblelog I needed a publication date and time for each article published. As I don't have an actual publication time I decided to use the end of day, as explained in A Matter of Time.

Edit: this blog post has been updated with additional code to make the RFC #822 solution work for a non-USA locale.

The end of day

In order to obtain a datetime Python object for the local end of day for a given date I came up with the following idea:

I accomplished this in Python as follows:

def get_end_of_day(date):
    return datetime.strptime(
        f'{date} 23:59:59', '%Y-%m-%d %H:%M:%S').astimezone()

Calling this function with the date of today returns:

>>> get_end_of_day('2019-10-09')
datetime.datetime(2019, 10, 9, 23, 59, 59, tzinfo=datetime.timezone(datetime.tim
edelta(seconds=7200), 'CEST'))

Note the additional time zone data (tzinfo); Central European Summer Time, which is correct for my location.

RFC #822

For the RSS feed I needed the pubDate to be in RFC #822 format, which I obtained as follows:

ctime = end_of_day.ctime()
pub_date = (f'{ctime[0:3]}, {} {ctime[4:7]}'
                + end_of_day.strftime(' %Y %H:%M:%S %z'))

Note that the short month name and the short day name are obtained from ctime instead of returned by strftime. The reason for this is that ctime returns those names in the USA locale, a requirement for RFC #822.

Moreover, it's tempting to use %Z instead of %z but note that, for example, CEST is not valid according to the RSS feed validator, which refers to section 5.1 of RFC #822. Hence, why digits must be used instead for a general solution.

An example of a pub_date value is:

Wed, 09 Oct 2019 23:59:59 +0200

RFC #3339

For the JSON feed I needed a date_published in RFC #3339 format, which was even easier to obtain as the string version of a datetime is correct except for a space instead of a T:

date_published = str(end_of_day).replace(' ', 'T')

An example of a date_published value is:


See Also