RFC 3339 formatting in Python
Update This post is outdated now; I changed a few things in rfc3339.py since this post. I created a page for rfc3339. It contains an up-to-date version & documentation.
For those who don't know, RFC 3339 is a date format aiming to be simple and unambiguous:
1985-04-12T23:20:50.52Z
The date and hour use the ISO format and T
is a marker to
indicate where the time starts. The Z
at the end indicates that the
time is expressed in UTC
Non-UTC timezone are expressed like this:
1996-12-19T16:39:57-08:00
The RFC 3339 is used in Atom a feed format, I am planning to implement it for Weblog. I tried to find a function to convert date/time into RFC 3339 strings in Python, and what I found was disappointing:
- PyFeed contains something to parse and generate RFC 3339 formatted dates. But it looks like it uses only timestamps and I want to use Python's datetime object. There was little documentation on the site and none in the package, just a few examples. What's the point of writing a library without proper documentation?
- This little function is nice but too limited.
- Formattime, a big project, again no documentation and depends on pytz and iso8601. Too big, 2 dependencies and not documented. You fail!
In the end I decided to write my own RFC 3339 conversion function. Simple, still powerful and documented! Dammit!
Here is a simple use case:
>>> import datetime >>> import rfc3339 >>> rfc3339.rfc3339(datetime.datetime(2008, 9, 4, 12, 34)) '2008-09-04T12:34:00-07:00'
Download the file: rfc3339.py
(See rfc3339.)
Here is the documentation (yes, that's rough), generated via pydoc
rfc3339
.
Help on module rfc3339:NAME rfc3339
FILE /home/henry/weblog/weblog/rfc3339.py
DESCRIPTION The function
rfc3339
formats dates according to the :RFC:3339
.rfc3339
tries to have as much as possible sensible defaults.FUNCTIONS rfc3339(date, utc=False, use_system_timezone=True) Return a string formatted according to the :RFC:
3339
. If called withutc=True
, it normalizesdate
to the UTC date. Ifdate
does not have any timezone information, uses the local timezone::>>> date = datetime.datetime(2008, 4, 2, 20) >>> rfc3339(date, utc=True, use_system_timezone=False) '2008-04-02T20:00:00Z' >>> rfc3339(date) # doctest: +ELLIPSIS '2008-04-02T20:00:00...' If called with `user_system_time=False` don't use the local timezone and consider the offset to UTC to be zero:: >>> rfc3339(date, use_system_timezone=False) '2008-04-02T20:00:00+00:00' `date` must be a a `datetime.datetime` or a timestamp as returned by `time.time()`:: >>> rfc3339(0, utc=True, use_system_timezone=False) '1970-01-01T00:00:00Z' >>> rfc3339(datetime.date.today()) Traceback (most recent call last): ... TypeError: excepted datetime, got date instead >>> rfc3339('foo bar') Traceback (most recent call last): ... TypeError: excepted datetime, got str instead
DATA all = ('rfc3339',) author = 'Henry Precheur <henry@precheur.org>' license = 'Public Domain'
AUTHOR Henry Precheur <henry@precheur.org>
The source code is in the Public domain