Python. How to create a local datetime with datetime.today()
The server sends a string that I striptime
and keep in a variable called here time_from_frontend
and then add a tzinfo like this:
import pytz
my_timezone = pytz.timezone("America/Guayaquil")
A = time_from_frontend.replace(tzinfo=my_timezone)
print A
print A.tzinfo
B = (datetime.datetime.today()).replace(tzinfo=my_timezone)
print B
print B.tzinfo
print B - A ?¿
Why do I get a huge difference between A and B? Here is what the terminal prints:
2016-02-11 20:00:00-05:19
America/Guayaquil
2016-02-12 01:08:35.478507-05:19
America/Guayaquil
5:08:35.478507
The frontend is sending me the actual time, when I do datetime.today()
and then specify the timezone, I thought I was gonna get a tiny difference between the A time and the B time (ie microseconds), but I get 5 hours. which is the timezone difference ("America/Guayaquil" is GMT-5).
I kind of understand the error. But how can I solve it? is there a way to create a datetime.today() object that corresponds to the local time?
I'm guessing that the datetime
from your frontend is in UTC. Doing a replace doesn't actually convert the datetime. It uses the data/hour/etc. and just uses a new timezone.
When you call datetime.today()
, you create a naive datetime without any timezone info. When you do a replace
on that, it's not actually doing a conversion either, it's just assuming the date you gave it is already in the timezone you provided, the same as the replace you did on the server time.
To actually convert datetimes to another timezone, you need to use astimezone
. If the datetime from the server is also naive and doesn't specify a timezone, astimezone
will error. To fix that. add a timezone of UTC
first.
time_from_frontend = time_from_frontend.replace(tzinfo=pytz.timezone('UTC'))
converted_server_time = time_from_frontend.astimezone(my_timezone)
datetime.today()
already returns the local datetime (the result is almost the same as datetime.now()
). Both return the local time as naive datetime objects (avoid them unless you want to display them immediately).
The correct way to get the current time in a given timezone is to use datetime.now(tz)
:
#!/usr/bin/env python
from datetime import datetime
import tzlocal # $ pip install tzlocal
local_time = datetime.now(tzlocal.get_localzone())
It works even during DST transitions when the local time may be ambiguous (using a naive datetime.today()
may fail in this case).
tzlocal
returns a pytz
tzinfo object and therefore it handles timezones that might have had a different UTC offset in the past (non-pytz code may fail in this case).
There are several issues in your code:
naive_dt.replace(tzinfo=tz)
where tz
has a non-fixed utc offset. Use tz.localize(naive_dt, is_dst=None)
instead the time difference in your question indicates that time_from_frontend
might be in UTC (not your local timezone) as @Brendan Abel suggested. To compare it with the current time, you could use datetime.utcnow()
if time_from_frontend
is a naive datetime object that represents UTC time:
time_diff = datetime.utcnow() - time_from_frontend
To get timezone-aware datetime, you can use .replace()
with UTC timezone (the utc offset is fixed -- it is always zero), :
frontend_time = time_from_frontend.replace(tzinfo=pytz.utc)
If both datetime objects are timezone-aware then the subtraction works too:
time_diff = local_time - frontend_time
See also:
上一篇: python:将输入写入文件并保存