Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

astimezone() cannot be applied to a naive datetime

Is possible timezones() and datetimes to get conflict with my OS in terms of time etc?

This is a silly question at first, because I got this problem and I cant see why or where it is happening from.

Looking to this:

def parse_datetime(a_datetime, account):
    tz = pytz.timezone(account.timezone_name)
    return datetime.astimezone(parser.parse(a_datetime), tz)

This function simply should return a nice datetime object as timezone(), just it! But dont!

All I know is that I get this message: astimezone() cannot be applied to a naive datetime()

Since I have friends with the same function and in their PCs the code runs alright, but in my case doesnt.

Especulations are: The configuration in your machine there is something is not okay...But, not for sure.

If there is anyone else that faced this and know what it is just reading what is here, well, would be nice if you tell me, I would be glad. Thanks in advance!

like image 720
R.R.C. Avatar asked Nov 04 '13 17:11

R.R.C.


1 Answers

You are using the wrong method to attach the timezone to the datetime object.

As documented on the pytz page you want to call that method on the datetime object, not on the class:

def parse_datetime(a_datetime, account):
    tz = pytz.timezone(account.timezone_name)
    return parser.parse(a_datetime).astimezone(tz)

This works only for already localized datetime objects (with, say, UTC as the timezone).

As the same documentation points out, you are better of using the .localize() method on the timezone object:

def parse_datetime(a_datetime, account):
    tz = pytz.timezone(account.timezone_name)
    return tz.localize(parser.parse(a_datetime))

This works on naive datetime objects, and does the correct thing for timezones with historical data too.

If you have mixed data, some with and some without timezones, then you should test for the timezone already being there:

def parse_datetime(a_datetime, account):
    dt = parser.parse(a_datetime)
    if dt.tzinfo is None:
        tz = pytz.timezone(account.timezone_name)
        dt = tz.localize(dt)
    return dt

Timestamps that already have a timezone attached will result in timezone-aware datetime objects and don't need to recast into another timezone.

like image 92
Martijn Pieters Avatar answered Oct 29 '22 06:10

Martijn Pieters