Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting timezone-aware datetime to local time in Python

How do you convert a timezone-aware datetime object to the equivalent non-timezone-aware datetime for the local timezone?

My particular application uses Django (although, this is in reality a generic Python question):

import iso8601 

....

date_str="2010-10-30T17:21:12Z" 

....

d = iso8601.parse_date(date_str)  foo = app.models.FooModel(the_date=d) foo.save() 

This causes Django to throw an error:

raise ValueError("MySQL backend does not support timezone-aware datetimes.") 

What I need is:

d = iso8601.parse_date(date_str) local_d = SOME_FUNCTION(d) foo = app.models.FooModel(the_date=local_d) 

What would SOME_FUNCTION be?

like image 793
kes Avatar asked Mar 27 '11 21:03

kes


People also ask

Is Python datetime timezone aware?

Timezone-aware objects are Python DateTime or time objects that include timezone information. An aware object represents a specific moment in time that is not open to interpretation.

How do you convert timezone to UTC in Python?

Use the pytz module, which comes with a full list of time zones + UTC. Figure out what the local timezone is, construct a timezone object from it, and manipulate and attach it to the naive datetime. Finally, use datetime. astimezone() method to convert the datetime to UTC.

How do I change timezone in Python?

Use the datetime. astimezone() method to convert the datetime from one timezone to another. This method uses an instance of the datetime object and returns a new datetime of a given timezone.


2 Answers

In general, to convert an arbitrary timezone-aware datetime to a naive (local) datetime, I'd use the pytz module and astimezone to convert to local time, and replace to make the datetime naive:

In [76]: import pytz  In [77]: est=pytz.timezone('US/Eastern')  In [78]: d.astimezone(est) Out[78]: datetime.datetime(2010, 10, 30, 13, 21, 12, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>)  In [79]: d.astimezone(est).replace(tzinfo=None) Out[79]: datetime.datetime(2010, 10, 30, 13, 21, 12) 

But since your particular datetime seems to be in the UTC timezone, you could do this instead:

In [65]: d Out[65]: datetime.datetime(2010, 10, 30, 17, 21, 12, tzinfo=tzutc())  In [66]: import datetime  In [67]: import calendar  In [68]: datetime.datetime.fromtimestamp(calendar.timegm(d.timetuple())) Out[68]: datetime.datetime(2010, 10, 30, 13, 21, 12) 

By the way, you might be better off storing the datetimes as naive UTC datetimes instead of naive local datetimes. That way, your data is local-time agnostic, and you only convert to local-time or any other timezone when necessary. Sort of analogous to working in unicode as much as possible, and encoding only when necessary.

So if you agree that storing the datetimes in naive UTC is the best way, then all you'd need to do is define:

local_d = d.replace(tzinfo=None) 
like image 146
unutbu Avatar answered Sep 16 '22 16:09

unutbu


In recent versions of Django (at least 1.4.1):

from django.utils.timezone import localtime  result = localtime(some_time_object) 
like image 28
user9876 Avatar answered Sep 20 '22 16:09

user9876