Understanding DateTime, tzinfo, timedelta & TimeZone Conversions in python

by Rama Vadakattu on February 18, 2009

python-logo 3289799486_fd7df39a73

In this post we will look at the common operations that are being performed on dates & time ,  converting  a datetime from one timzone to another timezone.

Common Operations:             How to get the present datetime?

In [189]: cdatetime = datetime.now()
In [190]: cdatetime
Out[190]: datetime.datetime(2009, 2, 17, 17, 34, 58, 407806)
It returns the current localdate and time.When i print cdatetime it  printed as a tuple of nine elements
(2009=year, 2=month, 17=day, 17=hour, 34=minutes, 58=seconds, 407806=microseconds, tzinfo is None and is not printed)
what each element in tuple represents is mentioned adjacent to that number.9-tuple is the basic  notation in python using which we create datetime objects as
dt = datetime(2009, 2, 17, 17, 34, 58, 407806).MOre details
http://docs.python.org/library/datetime.html#datetime.datetime

How to convert datetime into a well formatted string?

In [194]:  curdate.strftime("%d %b %Y %I:%M:%S %p")
.....:
Out[194]: '17 Feb 2009 05:18:27 PM'

printing the date in tuple format is not a good idea because it is not understood by most of the people.we want to convert that into a readable string.
strftime() is function we need to use to format the datetime into string.
"%d %b %Y %I:%M:%S %p"  is the format string each { %character} mentions how to print the repective components of datetime.
%M in format string specifies
Locale’s abbreviated month name
(means print Feb instead of 2)
%I in format string specifies Hour (12-hour clock) as a decimal number
(means print the time in 12hour format instead of 24 hr format)
you can find out various other directives ({%character} is called a directive) at the bottom of datetime module docs. http://docs.python.org/library/datetime.html

How to convert string to datetime object?

In [195]: dt = datetime.strptime('17 Feb 2009 04:22:11 PM','%d %b %Y %I:%M:%S %p')
In [196]: dt
Out[196]: datetime.datetime(2009, 2, 17, 16, 22, 11)
In [197]: dt.strftime("%d %b %Y %I:%M:%S %p")
Out[197]: '17 Feb 2009 04:22:11 PM'

most of time we recieve datetime ( ‘17 Feb 2009 04:22:11 PM’) as a string  from the user we need to make datetime object from that string.
strptime() is the function which does this task of converting string into datetime.
Format String "%d %b %Y %I:%M:%S %p" specifies the order in which the components of datetime will appear  and way in which they appear (i.e first day will appear as decimal representing day of the month,second month  will appear as  Locale’s abbreviated month name etc…)

How to convert a tuple into datetime object?

Out[87]: k =  (2009, 2, 17, 16, 22, 11)
In [89]: dt = datetime.datetime(*k[0:6])
In [206]: dt
Out[206]: datetime.datetime(2009, 2, 17, 16, 22, 11)
In [207]: dt.strftime("%d %b %Y %I:%M:%S %p")
Out[207]: '17 Feb 2009 04:22:11 PM'

Many times you encounter a situation where you need to form a datetime object from a tuple as shown above  (2009, 2, 17, 16, 22, 11).For example Universal feed parser gets blog entry date in 9 tuple format.
we use the  code dt = datetime.datetime(*k[0:6]) to convert it into datetime object.

Airthmetic with datetime: How to get two days back/after datetime from now ?

In [3]: curdate = datetime.now()
In [5]: curdate.strftime("%d %b %Y %I:%M:%S %p")
Out[5]: '18 Feb 2009 09:56:59 AM'
#gives you the two days back date
In [14]: curdate = curdate-timedelta(days=2)
In [15]: curdate.strftime("%d %b %Y %I:%M:%S %p")
Out[15]: '16 Feb 2009 09:56:59 AM'
#gives you the date after 3 days etc..
In [17]: curdate = curdate+timedelta(days=3,hours=5,minutes=5,milliseconds=1000)
In [18]: curdate.strftime("%d %b %Y %I:%M:%S %p")
Out[18]: '20 Feb 2009 03:07:51 PM'

1) timedelta object is being used to represent the duration. please  see in[14],in[17] for the various ways in which you can intialize timedelta objects.
MOre details at : http://docs.python.org/library/datetime.html#datetime.timedelta
2) use this timedelta object in airthmetic wih datetime (in[14]) to get the datetime before and after specified duration.)
With this timdelta object you can such answer questions such as 1) get the datetime after 45 days,before 1month etc..

How to check the timezone associated with datetime object?

The timezones in python are represented through an abstract base class called tzinfo. To assign a timezone to a datetime object  we need to create a subclass of tzinfo and attach this object to the datetime.tzinfo attribute as shown in the below examples.

In [211]: curdate = datetime.now()
In [212]:print  curdate.tzinfo
None

For the above object the timezone is null/None.These datetime objects are called naive datetime objects (i.e datetime objects who do not know their own timzone).We can’t perform timezone related operations on such naive objects.
if tzinfo is not null those objects are called Timezone aware objects we can perform timzone related operations on such objects.Below i will show you an example which clearly illustrates the process.
In [162]: class GMT5(tzinfo):
.....:     def utcoffset(self,dt):
#51/2 hours ahead of GMT
.....:         return timedelta(hours=5,minutes=30)
.....:     def tzname(self,dt):
.....:         return "GMT +5"
.....:     def dst(self,dt):
.....:         return timedelta(0)
In [171]: gmt5 = GMT5()
In [220]: curdate = datetime(2009,2,17,19,10,2,tzinfo=gmt5)
In [221]: curdate.tzinfo
Out[221]: <__main__.GMT5 object at 0x8a4b7cc>
In [222]:

Please follow the above code where i have shown you the  way to assign timzone object (tzinfo) to datetime object.
1) create an object which is a subclass of tzinfo.
2) overide the tzname,utcoffset,dst (Daylight Saving Time) methods to provide the offset,dst that this time zone has from GMT.(Every timezone is represented as an offset from Greenwhich mean time)
As the tzinfo is not null for the curdate.It is  timezone aware object.we can perform operations on such objects.
Below is another way to assign the timezone to datetime object.

In [172]: curdate = datetime.now()
In [173]: curdate = curdate.replace(tzinfo=gmt5)
In [174]: curdate
Out[174]: datetime.datetime(2009, 2, 17, 17, 18, 27, 593447, tzinfo=<__main__.GMT5 object at 0x8a4b7cc>)
In [176]: curdate.utcoffset()
Out[176]: datetime.timedelta(0, 19800)

curdate.utcoffset  will give you the  offset from GMT in seconds.THis method general used to intialize local timezone to naive datetime object which represents the local datetime.

Converting from one timezone to another timezone

Suppose we want to convert a datetime whose timezone  is +5:30 ahead of GMT (India) to another timezone whose timezone is ( -3:30 ) 3 1/2 hours behind GMT.
Below is the code which does this.

In [162]: class GMT5(tzinfo):
.....:     def utcoffset(self,dt):
#51/2 hours ahead of GMT
.....:         return timedelta(hours=5,minutes=30)
.....:     def tzname(self,dt):
.....:         return "GMT +5"
.....:     def dst(self,dt):
.....:         return timedelta(0)
In [171]: gmt5 = GMT5()
In [220]: curdate = datetime(2009,2,18,10,21,58,tzinfo=gmt5)
In [69]: curdate.strftime("%d %b %Y %I:%M:%S %p %Z")
Out[69]: '18 Feb 2009 10:21:58 AM GMT +5'
In [57]: class GMT3(tzinfo):
def utcoffset(self,dt):
#31/2 hours behind  GMT
return timedelta(hours=-3,minutes=30)
def tzname(self,dt):
return "GMT -3"
def dst(self,dt):
return timedelta(0)
....:
In [66]: gmt_3 = GMT3()
In [67]: newdate = curdate.astimezone(gmt_3)
In [70]: newdate.strftime("%d %b %Y %I:%M:%S %p %Z")
Out[70]: '18 Feb 2009 02:21:58 AM GMT -3'

1.create a timezone object (tzinfo) represeting the GMT-3 timezone.
2.use astimezone() function to convert the present locatime datetime(GMT+5:30) to (GMT-3:30)
as shown above. In next post we will discuss some more tips and tricks associated with dates and time.

Do you know?
Do you know any important tips and tricks which are helpful when working with dates and time? if yes please mention  in the comments.

Resources:
——————
http://docs.python.org/library/datetime.html#datetime.datetime
http://www.saltycrane.com/blog/2008/11/python-datetime-time-conversions/

Related posts:

  1. Understanding decorators
  2. Finding keywords using Python
  3. The magic of metaclasses in Python
  4. Python metaclasses and how Django uses them
  5. Beginning python

1 Tweet

{ 7 comments… read them below or add one }

1 Raja February 26, 2009 at 11:09 am

Dude, this is a waaay clearer explanation of python dates & times. Especially the tzinfo parts

2 Ian March 4, 2009 at 8:28 am

This is great. Just this week I was scratching my head trying to figure out TZs and the python documentation was confusing me. Thanks!

3 William March 19, 2009 at 11:32 am

You might also want to point people to PyTZ which provides a set of standard timezone definitions. Also, in the section about converting a datetime into a string, you may want to mention isoformat().

4 Rama Vadakattu March 20, 2009 at 5:20 am

@William Thanks for informing that.Will check those things and include it here very soon.

5 eternicode October 9, 2009 at 5:59 pm

python’s dateutil.parser.parse is a useful function for parsing tz-aware strings. For example, the twitter api gives each status a “created_at” attribute in the form of “Fri Oct 09 18:54:01 +0000 2009″. dateutil.parser.parse(“Fri Oct 09 18:54:01 +0000 2009″) returns a datetime object complete with a relevant tzinfo. From there, you can use datetime’s strftime to reformat the time, or time.mktime(datetime.timetuple()) to get a unix timestamp.

6 Mark Huang February 2, 2010 at 3:03 am

Wow, this is great! So much clearer than the Python docs!!

Leave a Comment

Additional comments powered by BackType

Previous post:

Next post: