rama
Comments
Reactions

Understanding DateTime, tzinfo, timedelta & TimeZone Conversions in python

By : rama

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/


Can we help you build amazing apps? Contact us today.

Topics : datetime

Comments

Raja

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

commmenttor
Ian 4th March, 2009

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

commmenttor
William 19th March, 2009

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().

commmenttor
Rama Vadakattu

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

commmenttor
eternicode

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.

commmenttor
Mark Huang 2nd Feb., 2010

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

commmenttor
tormen 12th May, 2010

If you only want to be able to translate between UTC and one other timezone
the following lines save you the usage of an external library (that most probably would not run with python3) AND you don't need to write (and maintain) a timezone class :-)
... but the code is NOT threadsave ... and needs to be run every time you want to convert (because you could switch to or from daylight saving) but still ... :-)

save current timezone:

origTZ = time.tzname

set timezone with which you want to calculate the difference relative to UTC:

os.environ['TZ'] = 'US/Eastern'; time.tzset()

get the timeDelta FROM UTC (so that: UTC + timeDelta = LOCAL):

timestamp = time.mktime( datetime.now().timetuple() )
timeDelta = datetime.utcfromtimestamp( timestamp ) - datetime.fromtimestamp( timestamp )

restore original timezone:

os.environ['TZ'] = origTZ[0]; time.tzset()

commmenttor
Sujay 11th Aug., 2010

Thank you for sharing such a useful information..........

commmenttor
dooby 20th Sept., 2010

@tormen
Thanks a lot man.. I was almost about to install PYTZ had I not come across the solution that you suggested.. Thanks for saving my all the time and energy, not to mention the pain.. :)

commmenttor
Alex

Good example of tzinfo, best explanation I've found. Cheers.

commmenttor
Brijin Sasankan 21st Jan., 2013

Clear explanation! :-)

commmenttor
zhkzyth

thanks for the post...It would be greate if you can organize the code to plain text..=)

commmenttor
Mike O'Connor 18th Nov., 2013

Rama... you saved me! I was nearly suicidal after attempting to read http://docs.python.org/release/2.5.2/lib/datetime-tzinfo.html.

Thanks so much.

-Mike

commmenttor

Reactions

jwesonga

Understanding DateTime, tzinfo, timedelta & TimeZone Conversions in python http://tr.im/s56r

This comment was originally posted on Twitter

© Agiliq, 2009-2012