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:

  • don't use 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:

  • How to get current time in Python
  • Python: How to get a value of datetime.today() that is “timezone aware”?
  • 链接地址: http://www.djcxy.com/p/40926.html

    上一篇: python:将输入写入文件并保存

    下一篇: 蟒蛇。 如何使用datetime.today()创建本地日期时间