Reputation: 1231
I am making a news blog for my project in which I have to display time under the news title as x minutes ago etc.
From the RSS feed of the news, I have the time stamp in the form of a string. For example:
timestamp = 'Tue, 12 Feb 2013 07:43:09 GMT'
I am trying to find the difference between this timestamp and the present time using datetime module in python. But for some reason it gives error:
ValueError: astimezone() cannot be applied to a naive datetime
I'll appreciate if somebody can point me in the right direction. Below is my attempt in Python:
from datetime import datetime
from pytz import timezone
timestamp = 'Tue, 12 Feb 2013 07:43:09 GMT'
t = datetime.strptime(timestamp, '%a, %d %b %Y %I:%M:%S %Z')
now_time = datetime.now(timezone('US/Pacific'))
# converting the timestamp to Pacific time
t_pacific = t.astimezone(timezone('US/Pacific')) # get error here
diff = t_pacific - t
Thanks! Prakhar
Upvotes: 1
Views: 2115
Reputation: 365717
The problem here is that t
does not have a timezone—that's what the error message means by "naive datetime". From the docs:
There are two kinds of date and time objects: “naive” and “aware”… An aware object has sufficient knowledge of… time zone and daylight savings time information… A naive object does not…
You can verify that it's naive by doing this:
print(t.tzinfo)
The answer will be None
.
As the astimezone
docs say:
self
must be aware (self.tzinfo
must not beNone
, andself.utcoffset()
must not returnNone
).
The strptime
function always generates a naive datetime.
You can fix this in various ways:
t
to a GMT datetime instead of a naive one, and then your conversion to 'US/Pacific'
will work.As the docs say, "If you merely want to attach a time zone object tz to a datetime dt without adjustment of date and time data, use dt.replace(tzinfo=tz)
." Since you know the time is in UTC, just replace
the empty tz with UTC, and you've got an aware time.
astimezone
, on which will assume UTC or which allows you to specify the source.There are various alternatives out there, but you're already using pytz
, so see its documentation.
now_time
to UTC instead of converting t
to PST.The last one is probably the simplest and best for most use cases. Since you've only got now_time
in PST because you explicitly asked for it that way, all you have to do is not do that (or explicitly ask for 'GMT'
instead of 'US/Pacific'
). Then you can just do your date arithmetic on UTC times.
If you need to display final results in PST, it's still often better to do the arithmetic in UTC, and convert at the end. (For example, you can have two times that are an hour apart, but have the same value in Pacific, because of 1am on DST day being repeated twice; that won't be an issue if you stay in UTC all the time.)
Upvotes: 2
Reputation: 43446
Your example had a few problems (I see you've fixed them now):
First line should be:
from datetime import datetime
It looks as though you're missing a closing parenthesis on the 4th line:
now_time = datetime.now(timezone('US/Pacific')
What is timezone()
? Where does that come from?
You don't really need to mess with timezones, I don't think — just use GMT (UTC). How about something more like this:
from datetime import datetime
timestamp = 'Tue, 12 Feb 2013 07:43:09 GMT'
t = datetime.strptime(timestamp, '%a, %d %b %Y %I:%M:%S %Z')
t_now = datetime.utcnow()
diff = t_now - t
Upvotes: 3