Alejandro Veintimilla
Alejandro Veintimilla

Reputation: 11523

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 (i.e 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?

Upvotes: 2

Views: 2811

Answers (2)

jfs
jfs

Reputation: 414149

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:

See also:

Upvotes: 1

Brendan Abel
Brendan Abel

Reputation: 37499

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)

Upvotes: 3

Related Questions