Working with Time
Notably missing from this page are the capabilities of the Python datetime module, which was introduced in 2.3 and is very powerful.
This page gives some basics of working with time in Python. More detail can be found in the time Module Documentation.
There are several ways to work with time:
seconds since the "Epoch"
The Epoch is January 1st, 1970, midnight, on UNIX systems. On other systems, look at the results of time.gmtime(0) to discover the date of the Epoch.
Measuring time in seconds since the Epoch is convenient for storage and comparing dates, because you only have a single number to consider.
The tuple contains several values, arranged the following way: year, month 1-12, day 1-31, hour 0-23, minutes 0-59, seconds 0-61, day 0-6 (Mon-Sun), day 1-366, and DST -1,0,+1. "DST" means "daylight savings time." For more information, see time Module Documentation.
Using a tuple is convenient, because you can access particular numbers by index, and because you can easily compare dates. Remember that Python compares tuple data from front to back. The data is indexed so that comparing tuple times is intuitive.
The string format reads something like "Mon Feb 16 16:04:25 2004". You can't really compare these usefully, but they're what you need to display things to the user.
Converting Between Formats
(see TimeTransitionsImage for image details)
mock ISO 8601
You can construct ISO 8601 with the following:
1 iso_time = time.strftime("%Y-%m-%dT%H:%M:%S", tuple_time)
You can revert the construction with the following:
1 tuple_time = time.strptime("2004-06-03T00:44:35", "%Y-%m-%dT%H:%M:%S")
The problem with this, though, is that if the string isn't formatted exactly like that, it won't be read. For instance, 20040603T00:44:35 is valid ISO8601, as is 20040603 for that matter, but neither will be read by the code above.
To account for both common inputs, you could use:
1 tuple_time = time.strptime(iso_time.replace("-", ""), "%Y%m%dT%H:%M:%S")
I seem to require receiving both while working with XmlRpc produced by a mix of both Python and Perl code. The XmlRpc specification is not very particular about the ISO8601 variant used for it's DateTime.
Note that this method does not handle time zones, so trying to parse 2004-06-03T12:34:56-0700 or 2004-06-03T12:34:56Z will fail. This is a fundamental limitation of time.strptime for which there is no easy workaround.
Parsing ISO 8601 with xml.utils.iso8601
If you have xml.utils.iso8601, you can do the following:
1 import xml.utils.iso8601 2 import time 3 4 # Present time, in ISO8601 5 print xml.utils.iso8601.tostring(time.time()) # returns "2004-04-10T04:44:08.19Z" 6 # From ISO8601 string, to seconds since epoch UTC 7 print xml.utils.iso8601.parse("2004-04-09T21:39:00-08:00") # -8:00 for Seattle, WA 8 # The epoch, in ISO8601 9 print xml.utils.iso8601.ctime(0) # returns "1969-12-31T16:00-08:00"
The module isn't perfect; If you omit the dashes, (perfectly valid ISO8601,) you'll get a ValueError exception. However, unlike time.strptime, xml.utils.iso8601.parse will handle the timezone specification correctly.
xml.utils is distributed in python-xml in debian and ubuntu, but appears to be unmaintained.
Parsing ISO 8601 with pyiso8601
http://pypi.python.org/pypi/iso8601/ provides a standalone ISO8601 parser.
Parsing ISO 8601 with python-dateutil
Although this isn't advertised as ISO8601 support, python-dateutil seems to deal with the format correctly (for example, it has time zone support). python-dateutil's latest versions are only for Python 3.x. For Python 2.x compatibility, you need to stick to python-dateutil 1.x. For example, with pip: pip install 'python-dateutil < 2.0'.
import dateutil.parser dateutil.parser.parse('2008-08-09T18:39:22Z')
Parsing RFC 3339 with the rfc3339 module
RFC 3339 is the standard datetime format for most internet and web standards. It is a stricter ISO8601 profile, restricted to datetimes of second resolution or more precise. It requires explicit timezones as offsets from UTC.
ISO8601 and Python in general
All in all, reading ISO8601 time values is non-trivial. For example, it is possible that someone can specify a full day, or a full week even, in ISO format. You can also specify days by number, if I recall correctly.
Generally, programs conceed to accept only a limited subset of ISO8601. That subset tends to be "yyyy-mm-ddThh:mm:ss" and then either ".mmmmmm" sub-seconds or "+hh:00"/"-hh:00" for time zone.
This page is meant just to give you the basics. You may also want to read:
Official nomencalture and description for 8601: http://www.standardsdirect.org/standards/standards3/StandardsCatalogue24_view_23407.html
mxDateTime python extension module. provides many interfaces for handling dates and times, including ISO 8601 handling: http://www.egenix.com/files/python/mxDateTime.html