Recently for my work I had to do some date/time-wrangling in Python. We have a database containing unix timestamp values, and the front-end application needs to talk local time. The necessary conversions aren’t so complicated, but Python makes life a bit harder by having three relevant modules, three relevant data types (not matching the modules), and a complicated web of conversion possibilities between them.

For instance:

  • the datetime class lives in the datetime module; careful with your imports, you will want both!
  • the datetime module has a time class, but there’s also a time module
  • the documentation talks at different places about “time tuples” and also about “time.struct_time” objects; they’re the same thing
  • to convert a unix timestamp to a time tuple representing UTC time, you use time.gmtime(); for the reverse conversion, you use calendar.timegm() (this is the only place you’ll use the calendar module)
  • to get now you use:
    • time.localtime() if you want a timetuple
    • time.time() if you want a unix timestamp
    • if you want a datetime object
    • time.gmtime() if you want a timetuple representing UTC time
    • datetime.utcnow() if you want a datetime object representing UTC time
    • a crowbar if necessary
  • to build a datetime object from a time-tuple, you can set the fields one-by-one… or you can slice the time-tuple and unpack the list: datetime(*a_time_tuple[:6])

In other words, there’s a lot of fiddly detail to remember. So I made a chart.

Blurry overview of python date/time wrangling

Click through for (non-blurry) PDF.

It’s formatted for a4 paper and prints nicely. I used the incredible LaTeX drawing system TikZ. (On my screen the arrows have a little glitch at start and finish, but it doesn’t appear in my printout. Possibly a TikZ bug? Not sure.)

Note that it doesn’t show everything you can do; apart from the more egregious omissions (like timezone handling on datetime objects, which actually seems quite straight-forward but didn’t fit nicely into the design), I didn’t include arrows for nonsensical operations. For example you could feed a UTC time-tuple into time.mktime() (which takes a localtime time-tuple to a unix timestamp), but the result would be nonsense: the number of seconds since a date similar to, but probably not quite the same as, the unix epoch.