Skip to content

Python datetime conversions

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
    • datetime.now() 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.

4 Comments

  1. Wow, man, we are printing it and putting on the wall in our office. Thanks! Of course, you DO know that you really want to use UTC everywhere, unless the circumstances really force you to use local time, for the sake of your sanity, right?

    The datetime library is rather complex, but the domain itself is really complicated, and Python’s implementation is pretty complete. For example, did you know that it allows you to (easilishly) handle stuff like the double summer time the British fancied during WW2?

    Tuesday, August 17, 2010 at 12:59 am | Permalink
  2. tikitu wrote:

    Glad you like it! (Of course let me know if anything is wrong or missing…)

    Using UTC: the tricky thing is, the people using the app speak localtime. So at least at the UI layer you need to translate back and forth. (And under certain circumstances, the dates you get out of a database might be automagically localtimed as well, gr.)

    I assume you handle double summer time by putting in a tzinfo object (and writing that baby must be a nightmare); I steered entirely clear of that, the naive objects were enough headache…

    Tuesday, August 17, 2010 at 10:01 am | Permalink
  3. Robin wrote:

    apt-get source tzdata and poke through the files there, there’s all sorts of bits of history of time changes. There’s actually something similar I think that goes into more detail, but I’m failing to find it at the moment.

    Tuesday, August 17, 2010 at 11:21 am | Permalink
  4. This looks suspiciously like a PHP library.

    Thursday, August 19, 2010 at 1:00 pm | Permalink