22
Working with datetime module and timezones in Python
Python
Datetime
Timezone

I generally find Python a very versatile language that allows you to do a lot of things without having to expend a lot of effort. However I have run into some issues with the datetime module.

For basic purpose the datetime module is quite sufficient, but the sadly timezones cannot be manipulated and used just with the datetime module. For example a simple task as converting the date time object from one timezone to another can be pretty daunting. So I will use this as an example to show how you can deal with timezones.

A simple datetime object is called timezone naive. So when we do the following

from datetime import datetime
now = datetime.now()

This creates a datetime object, that does not have any information about the timezone, and uses the current time of the system. To use timezone with it, you need to convert this into a timezone aware aware object. This can be done with using the replace function as follows

# suppose you have the desired timezone in the variable tz    
now = now.replace(tzinfo = tz)

There are two things, first how can we get the tzinfo object, and second is, does the now object contain the correct datetime according to the timezone that you have entered. I will come to the first part later, but the answer to the second part is NO.

What replace does is that it just populates the tzinfo field, and simply accepts that you have given the correct timezone for the datetime. So suppose you are in India (your timezone being Asia/Kolkata) and you set the tzinfo for Europe/Berlin then it would simply accept that the current time of the system is actually the Europe/Berlin system, which is actually wrong.

So if you want to convert datetime from one timezone to another, you have to use astimezone

now = datetime.now()
now = now.replace(tzinfo = tz)
now = now.astimezone(tz)

Here we must see that we cannot directly use astimezone because datetime.now() gives us a timezone naive object and we can use astimezone only on a timezone aware object. So although the middle line seems to be useless, we nevertheless have to use it.

Now coming to the point how we can get the different timezones. And that is not a very straight forward task. We have to use two modules for that dateutil and pytz both of which are pretty handy. So if we need to get the current timezone then we would do the following

from dateutil.tz import *
# This contains the local timezone 
local = tzlocal()
now = datetime.now()
now = now.replace(tzinfo = local)

# prints a timezone aware datetime
print now

And suppose we want to convert this to utc datetime then we would do

utc = tzutc()
utc_now = now.astimezone(utc)
print utc_now

Using just the dateutil module does not give us a lot of flexibility because we can only get the tzlocal() and tzutc(), but what if we have to convert datetime to some other timezone. In that case we will have to use pytz module. Suppose you know that your timezone is 'Asia\Kolkata' and you want to convert datetime from some other timezone you would do the following

import pytz

# assuming now contains a timezone aware datetime
tz = pytz.timezone('Asia/Kolkata')
your_now = now.astimezone(tz)
print your_now

As I said before the dateutil and pytz modules are pretty handy and can be used for other things as well. You are free to explore them if you want to. Just to give an example suppose you have a datetime in string as 5 P.M. 21st January dateutil can parse it into a datetime object as

from dateutil.parser import *
parse("5 P.M. 21st January")

Note: If you are using dateutil with python2.x you are likely to get an error because they are some incompatibilities, so you must also install python-dateutil==1.5

Author

Notifications

?