Dealing with datetimes like a pro in Python

Irina Truong
j-bennet codes
Published in
3 min readDec 8, 2017

Imagine you write an application similar to Google Analytics. It collects events from websites, and displays nice tables and charts to customers. Customers only have to install a little snippet of JavaScript on their websites, for the events to be sent to the server. Here is how an event might look:

Challenge #1: Parsing datetimes

Of course, you use Python, because it’s the best language ever! You parse the events, and convert the date and time part to a datetime type.

After the cleanup, parsing, and categorizing of browsers and referrers, customers see a nice table of events:

And… they don’t like it.

Why?

Challenge #2: Displaying datetimes with timezones

First, this generic date format (RFC 3339) doesn’t look very appealing. Americans expect to see their familiar “M/D/Y” and 12-hour clock (AM/PM). Europeans are looking for “D/M/Y”, and some of them “D.M.Y”, and mostly 24-hour clock.

Then, all the dates and times are in UTC (this is how the server logs them). So the customers have to squint and think “Hey, when did this really happen?” — and do timezone offsets in their head (don’t even get me started on DST) — and this is hard work!

So you decide to convert the dates and times into local timezones before displaying the information.

Here, you hit the first roadblock. The Python standard library contains an abstract class tzinfo, but it’s not possible to create an instance of it! Where is the concrete class?

It appears that the implementation of tzinfo can be found in the third-party library called pytz. This library provides instances of the IANA timezone database (https://www.iana.org/time-zones). Here is how you use it:

Now you’re happy with how things look. But you’re not done yet!

Challenge #3: Rounding (truncating) datetimes

Next, you want to show the data in aggregated form, to count how many views each URL collected. This would make the data even more useful, and the customers even happier.

To aggregate on hours, you write a little piece of code that rounds datetimes down to an hour:

Here is what you get after aggregating:

Challenge # 4: Finding edges of an interval

You’d like to add another feature: comparing weeks of data. How does this week’s activity look, compared to the last week’s, did the pages get more views, or less?

To be able to do that, you need to determine when the week started:

And when the previous week started:

Now, you can select and sum up the data between those.

Challenge #5: Creating ranges

Next, you want to enable the customers to select their own start and end of an interval. That means generating a range of dates. For that, you import another module called dateutil:

Whew. You did some great work there!

Did it have to be this complicated?

Don’t you wish the datetime class already had all the handy methods for rounding, truncating, converting, parsing, formatting, and arithmetics?

It can — with Pendulum.

Pendulum?

Pendulum is an open-source Python library created to provide a better, smarter drop-in datetime replacement. Source code: https://github.com/sdispater/pendulum.

I should also mention arrow (https://github.com/crsmithdev/arrow). Arrow is an older and better known library that solves the same problem as Pendulum: provides a richer, more convenient API for datetime, filling the gaps of the standard library.

However, I’m going to concentrate on Pendulum, because it fixes some of arrow’s bugs and problems. It is more consistent and robust (at the expense of some performance).

What do you mean by drop-in replacement?

Instead of importing and instantiating datetime.datetime, you import pendulum and create an instance of Pendulum class. That instance has everything that datetime would have normally, and can be used in the code that previously accepted datetime, but has more functionality.

Let’s use it!

Parse the datetime string:

Convert to user’s timezone:

Round down to an hour:

Calculate the last Monday:

Calculate the next Monday:

Create a range of dates:

Wasn’t that easy?

Another advantage of using Pendulum — since it’s an open-source library with lots and lots of users, they already worked out and fixed most of the bugs that you might have run into, have you used your methods and wrappers to do the same thing. Moreover, you can be one of the people filing and / or fixing the issues!

Datetimes don’t have to be so hard, after all.

--

--