By Jochen Voss, last updated 2012-02-18
There are many different ways to represent date and time in Python programs. This page gives an overview over the different methods and explains how to convert between different representations. The main focus of this page is on how to represent points in time often assuming some fixed, local time zone. This is used for example when analysing log files. I will not explain here how to convert between different time zones or between different calendars.
The international standard ISO 8601 describes a string representation for dates and times. Two simple examples of this format are
2007-03-04 20:32:17 20070304T203217
(which both stand for the 4th of March 2007, a bit after half past eight in the evening) but the format also allows for sub-second resolution times and to specify time zones. This format is of course not Python specific, but it is good for storing dates and times in a portable format. Details about this format can be found in the ISO 8601 wikipedia entry and on Markus Kuhn's ISO 8601 page.
I recommend use of this format to store times in files.
One way to get the current time in this representation is to use
strftime
from the time
module in the Python
standard library:
>>> from time import strftime >>> strftime("%Y-%m-%d %H:%M:%S") '2007-03-03 22:14:39'
datetime
ObjectsThe
datetime
module
of the Python standard library provides the
datetime
class.
I recommend use of this format, when possible, to represent times in Python programs.
One way to get the current time in this representation is to use the
now
method of the datetime
class in the Python
standard library:
>>> from datetime import datetime >>> datetime.now() datetime.datetime(2007, 3, 3, 22, 20, 11, 443849)
The traditional way to describe times on a Unix system is to give the number of seconds elapsed since the beginning of the year 1970. Sometimes this count includes leap seconds and sometimes it does not. Traditionally this number is an integer, but of course one can get sub-second resolution by using floating point numbers here.
One way to get the current time in this representation is to use
time
from the time
module in the Python standard
library. This function returns the number of seconds elapsed since the
beginning of the year 1970 in UTC as a float:
>>> from time import time >>> time() 1172960204.226908
This is what is represented by struct_time
objects in
Python (and similarly by struct tm
in the C standard
library). Time is represented as a tuple consisting of the following
fields:
It is not possible to get sub-second resolution in this representation.
For details see the
time
module
description of the Python standard library.
One way to get the current time in this representation is to use
localtime
from the time
module in the Python
standard library:
>>> from time import localtime >>> localtime() (2007, 3, 3, 22, 13, 27, 5, 62, 0)
mxDateTime
ClassEgenix provides the
mxDateTime class
as part of their mx
extensions for Python. This class seems
to be relatively similar to the standard datetime
class, but
it provides a parser for ISO 8601 date strings.
One way to get the current time in this representation is to use the
now
constructor from the mx.DateTime
module:
>>> from mx.DateTime import now >>> now() <DateTime object for '2007-03-03 22:51:13.37' at 52a2c0>
The very nice
matplotlib graphing
library has support for using dates to locate data in plots. The library
represents dates/times as single floating point numbers and provides
functions num2date
and date2num
to convert
between Python datetime
objects and the matplotlib
representation. The numbers represent days but I am not sure which day in
time is matplotlib day 0.
One way to get the current time in this representation is as follows:
>>> from matplotlib.dates import date2num >>> from datetime import datetime >>> date2num(datetime.now()) 732738.96073077701
Since I recommend to normally use the standard Python
datetime
class to store times in Python programs, I only
provide recipes here to convert between datetime
and any of
the other representations here. A summary of the described methods can be
found in table 1 below.
datetime
Unfortunately there is no easy way to parse full ISO 8601 dates
using the Python standard library. If you know the exact format of the
date string in advance, you can use the strptime
constructor
of the datetime
class (new in Python version 2.5):
>>> from datetime import datetime >>> datetime.strptime("2007-03-04 21:08:12", "%Y-%m-%d %H:%M:%S") datetime.datetime(2007, 3, 4, 21, 8, 12)
There are several parsers available in external modules. The most robust one I found is contained in the Egenix mxDateTime module:
>>> from mx.DateTime.ISO import ParseDateTimeUTC >>> from datetime import datetime >>> x = ParseDateTimeUTC("2007-03-04 21:08:12") >>> datetime.fromtimestamp(x) datetime.datetime(2007, 3, 4, 21, 8, 12)
Another parser is available in the dateutil module:
>>> import dateutil.parser >>> dateutil.parser.parse("2007-03-04 21:08:12") datetime.datetime(2007, 3, 4, 21, 8, 12) >>> dateutil.parser.parse("2007-03-04 22:08:12-0100") datetime.datetime(2007, 3, 4, 22, 8, 12, tzinfo=tzoffset(None, -3600)) >>> dateutil.parser.parse("2001-11-12T12:13:00+01:00") datetime.datetime(2001, 11, 12, 12, 13, tzinfo=tzoffset(None, 3600))
Conversion from datetime
objects to ISO time strings is
easy using the strftime
method:
>>> from datetime import datetime >>> t = datetime.now() >>> t.strftime("%Y-%m-%d %H:%M:%S") '2007-03-04 00:15:12'
datetime
To convert a Unix time stamp to datetime
use the
fromtimestamp
constructor:
>>> from datetime import datetime >>> datetime.fromtimestamp(1172969203.1) datetime.datetime(2007, 3, 4, 0, 46, 43, 100000)
To convert a datetime
object into a Unix time stamp, one
has to first convert it into a struct_time
:
>>> from datetime import datetime >>> from time import mktime >>> t=datetime.now() >>> mktime(t.timetuple())+1e-6*t.microsecond 1172970859.472672
struct_time
and datetime
struct_time
objects can be converted to
datetime
objects using the normal datetime
constructor:
>>> from time import localtime >>> from datetime import datetime >>> x = localtime() >>> datetime(*x[:6]) datetime.datetime(2007, 3, 4, 1, 0, 39)
datetime
objects can be converted back to
struct_time
using the timetuple
class method:
>>> from datetime import datetime >>> t = datetime.now() >>> t.timetuple() (2007, 3, 4, 1, 3, 18, 6, 63, -1)
datetime
mxDateTime
objects can be converted to
datetime
via the Unix time stamp format:
>>> from mx.DateTime import now >>> from datetime import datetime >>> x = now() >>> datetime.fromtimestamp(x) datetime.datetime(2007, 3, 4, 1, 14, 19, 472672)
The reverse conversion is a bit awkward:
>>> from mx.DateTime import DateTime >>> from datetime import datetime >>> t = datetime.now() >>> DateTime(t.year,t.month,t.day,t.hour,t.minute,t.second+1e-6*t.microsecond) <DateTime object for '2007-03-04 01:14:19.47' at 104a368>
datetime
This conversion is straight-forward using the converter functions provided by matplotlib:
>>> from matplotlib.dates import num2date >>> num2date(732738.96073077701) datetime.datetime(2007, 3, 3, 23, 3, 27, 139133, tzinfo=<UTC>)
and
>>> from matplotlib.dates import date2num >>> from datetime import datetime >>> t = datetime.now() >>> date2num(t) 732738.96073077701
Table 1 summarises the conversion methods discussed in this chapter.
Time Representation | conversion to datetime
| conversion from datetime
|
---|---|---|
ISO strings | Difficult with the standard library, see text. | t.strftime("%Y-%m-%dT%H:%M:%S")
|
Unix time | datetime.fromtimestamp(x)
| mktime(t.timetuple())+1e-6*t.microsecond
|
struct_time | datetime(*x[:6])
| t.timetuple()
|
mxDateTime | datetime.fromtimestamp(x)
| see text |
matplotlib | num2date(x)
| date2num(t)
|
Table 1. Summary of the different
conversions to and from the Python standard library's
datetime
class. The value t
always stands for a
value in the representation given in the first column, x
denotes datetime
objects.
time
module
documentation.
datetime
class
documentation.
Copyright © 2012 Jochen Voss. All content on this website (including text, pictures, and any other original works), unless otherwise noted, is licensed under the CC BY-SA 4.0 license.