Skip to content

Python date/time libraries

July 27, 2015

This is an overview of the various date/time implementations in Python (that I know of) and why they aren’t good enough. I’m not mentioning why they are good, they may or may not be. The standard library’s datetime module has a lot going for it. This only explains why it’s not good enough. If I’ve missed a library, tell me and I’ll take a look.

The standard library modules

  • Too many separate modules, datetime, time, calendaring, etc, with some overlap (and omissions).

  • Naive and intentionally crippled timezone implementation.

  • Stores datetimes internally as the local time, which makes time zones overly complicated.

  • timedelta has a days attribute which is actually not 1 day, but 24 hours.

  • Except that the intentionally crippled datetime implementation makes it 23 or 25 hours on DST changes.

Arrow

  • Arrows main criticism towards the standard library is that there is too many classes, like date, time and datetime. However, Arrow does not implement a date() replacement or a time() replacement, an Arrow() object only replaces datetime(). You can’t represent a date or a time with it, Arrow(2014, 5, 6) will return midnight that day. It also will return a timedelta if you subtract two Arrow objects. So it does not improve the situation. Even if you replace all your datetime objects with Arrows, just still need to deal with the exact same number of classes.

    And how should time arithmetic work on a date? What is “The 1st of February plus three minutes”? That’s not obvious. A date is the whole day so it actually should be three minutes after midnight on February 2nd”, but if you implement that I think most people would be very surprised. They would get even more surprised that datetime(2014, 11, 2, 5) – datetime(2014, 11, 2) doesn’t return a 5 hour timedelta. (Actual elapsed time between midnight and 5 am that day is six hours). And even if you implement one object that can behave both as a date and a datetime. How can you tell the difference between a date and a datetime without asking the object if they are the same type?

    I therefore think there should be separate date and datetime objects.

  • In addition I’m not happy about how Arrow.replace() works, with Arrow.replace(month=3) sets the month to March, but Arrow.replace(months=3) increases it with three months. The difference is to subtle, and the replace() method should replace, not add. A shift() method would have been better.

  • All Arrow objects are time zone aware, and default to UTC. But separating time zone aware objects and time zone naive classes are essential, as again, they can’t reliably be compared or subtracted. Just assuming that not specifying a time zone means UTC is not good enough for all cases.

Times

  • Uses Arrow as it’s implementation, so only included here for completeness.
  • Deprecated.

Moment

  • Datetimes are mutable, and they shouldn’t be, because then you can’t use them as keys etc. Possibly there could be mutable datetimes as well, but that should not be the default.

  • Merges dates and datetimes into one class.

DateTime

  • Old, inconsistent and confusing due to being written/extended piecemeal.
  • A lot of old cruft like supporting timezones named “EST”.
  • Unmaintained.

mxDateTime

  • No real time zone support.

dateutil

  • Implements a relativedelta class, but uses the stdlib for everything else, so only included for completness.

Delorean

  • A wrapper around datetime and pytz, chiefly for a more convenient API (I think).

From → python

9 Comments
  1. Can I ask a dumb question? Is there any language (standard library or other) that actually gets dates/times good enough? Or is this just a nasty little problem?

    • It’s definitely a very tricky problem. I haven’t looked into this in detail, but the new Java library looks OK, and there is also a good 3-party library for Java. But I know both of these libraries uses a 0-indexed month which is amazingly confusing. I’m not currently aware of any library that gets everything right, but I definitely am not an expert on that question.

    • One of the first time-handling libraries I used was in 1991, and was written for systems running on ships (and hence time zones handling was important). I don’t believe it suffered from any of these problems. Ever since then, every time-handling library I’ve seen has been a disappointment.

  2. There’s also delorean (https://delorean.readthedocs.org/en/latest/) that I know of. I haven’t used it, but I’ve been hearing some good about it.

  3. The criticism of arrow is rather silly; instead of the timedelta interface you should be using the replace interface provided by arrow which is both succinct and much more intuitive than using timedelta’s regardless of the datetime class.

    http://crsmithdev.com/arrow/#replace-shift

    • With Arrow I attempted to criticize that it doesn’t have separate date() objects, not that it doesn’t have timedeltas. It does support the stdlib timedeltas. It supports the stdlib date() objects as well, more or less, though, so what I wrote was definitely unclear. I rewrote the Arrow section to go into details of what I meant.

  4. pboddie permalink

    I see there’s a long thread about datetimes on python-dev, but what I’m missing is really a way to conveniently refer to datetimes in terms of what I call “time regimes” (Europe/Stockholm, for instance) rather than UTC offsets and DST flags, which is what zone-aware datetimes appear to employ (tzname returns CEST, for instance). I’m currently messing around with iCalendar data, and may well end up making a proper abstraction myself for this, even though I dislike making yet more datetime abstractions (having actually tried to embrace the datetime module’s classes this time round).

    Also, abstractions for things like years and months are usually omitted completely from date and time handling libraries. Naturally, they don’t easily “combine” with other things, but they can be very useful instead of faking them with things like the first day of the year/month and other such hacks.

    None of this is particularly easy – look at the original Java date API – and there are lots of special cases depending on applications (as the usual python-dev grandstanding illustrates). But we should be quite a bit wiser about things that work now than we were.

    • You need either pytz or python-dateutil for this, they both implement support for the zoneinfo database. Which one you pick is a matter of taste.

      dateutil also includes a lot of other nifty tools, like support for iCalendar rrules etc.

      • pboddie permalink

        I already use pytz to get zone-aware datetimes, and they do report their “regimes” in the object representation…

        datetime.datetime(2015, 7, 28, 23, 3, tzinfo=)

        And looking at it now, the tzinfo attribute on aware datetimes provides a zone attribute that returns such information. So maybe I can get away with using that.

        I personally prefer pytz’s API to dateutil, and from memory I think the documentation is better, too.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: