playing with timezone using pytz
Tweetin programming · Wed 11 May 2011
in programming · Wed 11 May 2011
World Timezone Image from www.physicalgeography.net
When we develop web applications sometimes we need multiple timezone support. If we don’t have any previous experience then it might be a tough and confusing job. Here I will help you to get some basics of Timezone conversion.
I have been used timezone with django application, but the concept is same for all languages.So here I will explain things using python timezone module "pytz". You have to install this module first into your system by using "easy_install"
Install python timezone module.
#easy_install pytz
This python module support all major time zones and it helps to convert date and time in one timezone to any other timezones.You can use the human readable time zone names in pytz module to represent the local time zones.( like Asia/Kolkata, Europe/Paris, EST etc. ).
When we deal with multiple timezone in our application, we might have backend database where we store these date and time information. Most databases support UTC as it's the common timezone format. And it's better to keep a unique timezone information when saving the date and time in database and database engines not going to support all timezone formats directly. So we need to stick with commonly used UTC/GMT (Coordinated Universal Time) timezone format , it also helps to remove the daylight saving issues.
Here is the strategies used in web applications with multiple timezone support :-
Bellow I'm explaining some real scenarios where we need to change time zone information from UTC to local and vice versa,
We always save date and time information in the database as UTC standard. In django/Rails or other Frames we have an option to set Projects default timezone as UTC. So in our database the time and date are always in UTC. If above methods are not ing for your application you manually need to convert the local system time into UTC format and then save it. Below code sample explain things more clearly,
haridas@haridas-debian:~$ python
Python 2.6.6 (r266:84292, Dec 27 2010, 00:02:40)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> import pytz
>>> import datetime
>>> local_system = datetime.datetime.now() #Get local system time and
date.
>>> local_system
datetime.datetime(2011, 5, 7, 9, 42, 23, 751976)
>>>
>>> local_system_utc = datetime.datetime.utcnow() # utcnow() function
give the UTC time of current local time.
>>> local_system_utc # But this date tuple doesn't have the timezone
information.
datetime.datetime(2011, 5, 7, 5, 42, 49, 253618) #We call it as Naive
representation(Date object without Timezone information.)
>>>
>>> local_system_utc.tzinfo #This output None value or nothing.
>>>
>>>
>>> local_system_utc = pytz.utc.localize(local_system_utc) #Adding
timezone information to "local_system_utc"
>>>
>>> local_system_utc
datetime.datetime(2011, 5, 7, 5, 42, 49, 253618, tzinfo=<UTC>) #you can
see the tzinfo variable included with the datetime tuple.
#But when saving UTC time inside DB you can use naive representation of
datetime object in UTC.
#You can do the tzinfo addition when retrieving the time from DB.
By this way we can save time and date in Database even-though users are from a different timezone. We need to consider them only when retrieving the time object from database, ie; we need to convert our UTC time to user specific timezone. So this conversion is only for view purposes.
We need to convert UTC times to corresponding user timezone, follow the bellow method,
>>> import pytz
>>> import datetime
>>>
>>> now_utc = datetime.datetime.utcnow() #Our UTC naive time from DB,
For the time being here I'm taking it as the current system UTC time..
>>> now_utc
datetime.datetime(2011, 5, 9, 6, 36, 39, 883479) # UTC time in Naive
form.
>>>
>>> local_tz = pytz.timezone('Europe/Paris') #Our Local timezone, to
which we want to convert the UTC time.
>>>
>>> now_utc = pytz.utc.localize(now_utc) #Add Timezone information to
UTC time.
>>>
>>> now_utc
datetime.datetime(2011, 5, 9, 6, 36, 39, 883479, tzinfo=<UTC>) # The
full datetime tuple
>>>
>>> local_time = now_utc.astimezone(local\_tz) # Convert to local
time.
>>>
>>> local_time #Current local time in Paris
datetime.datetime(2011, 5, 9, 8, 36, 39, 883479, tzinfo=<DstTzInfo
'Europe/Paris' CEST+2:00:00 DST>)
>>>
Rather than just conversion of UTC time, sometimes we need to fetch records from the Database in between particular interval of local time time, for eg; From 07:00 Morning to 22:30 Evening of local time. Here our data is in UTC format, so we need to get the corresponding UTC time of these local time interval and then search the DB, you can follow bellow method,
You can reconstruct the javascript string format of the date in to python date object by,
>>> import datetime
>>> import pytz
>>>
>>>
datetime.datetime(year=2011,month=6,day=7,hour=10,minute=26,second=45)
datetime.datetime(2011, 6, 7, 10, 26, 45)
>>> local_date =
datetime.datetime(year=2011,month=6,day=7,hour=10,minute=26,second=45)
>>>
>>>
#From DB we will get the corresponding users timezone information , for
eg; we can take 'America/Chicago' as our local timezone.
>>> timezone = pytz.timezone('America/Chicago')
>>> local_std_date = timezone.localize(local\_date,is\_dst=True)
>>>
>>> local_std_date
datetime.datetime(2011, 6, 7, 10, 26, 45, tzinfo=<DstTzInfo
'America/Chicago' CDT-1 day, 19:00:00 DST>)
>>>
>>>
#Now you have standard localtime and it can be easily converted to the
UTC and then do the Database search and other things.
>>> local_utc = local_std\_date.astimezone(pytz.utc)
>>> local_utc
datetime.datetime(2011, 6, 7, 15, 26, 45, tzinfo=<UTC>)
>>>