I have been working with time zones in Python for some time now. One of my challenges was creating an prize which was valid up to 23:59:59 on the proper time zone some days after the current time. I took the current UTC time, added a timedelta, converted to the desired time zone, replaced hour/minutes/seconds and converted back to UTC. That worked and still works perfectly.
Recently I tried to rewrite that code on another project and came to a situation which I cannot explain. Check out the example code below.
from datetime import datetime
import pytz
dt1 = datetime\
.now(pytz.utc)\
.astimezone(pytz.timezone("America/Sao_Paulo"))\
.replace(
year=2018,
month=3,
day=22,
hour=23,
minute=59,
second=59,
microsecond=0
)\
.astimezone(pytz.utc)
dt2=datetime(
year=2018,
month=3,
day=22,
hour=23,
minute=59,
second=59,
microsecond=0,
tzinfo=pytz.timezone("America/Sao_Paulo")
)\
.astimezone(pytz.utc)
print(dt1)
# 2018-03-23 02:59:59+00:00
print(dt2)
# 2018-03-23 03:05:59+00:00
Why dt1 != dt2
?
I know dt1
is an ugly way to create a datetime
object, but that is actually the value I expect. I cannot understand why they differ in 6 minutes.
Thank you very much.
答案 0 :(得分:1)
Quoting from the pytz documentation :
Unfortunately using the tzinfo argument of the standard datetime constructors ‘’does not work’’ with pytz for many timezones.
Take a look at your dt2 before converting it to UTC and you'll see there's something fishy going on with its UTC offset:
>>> dt2 = datetime(year=2018, month=3, day=22,
... hour=23, minute=59, second=59,
... tzinfo=pytz.timezone("America/Sao_Paulo"))
>>> print(dt2)
2018-03-22 23:59:59-03:06
This on the other hand works:
>>> naive_dt = datetime(year=2018, month=3, day=22,
... hour=23, minute=59, second=59)
>>> aware_dt = pytz.timezone('America/Sao_Paulo').localize(naive_dt)
>>> print(aware_dt)
2018-03-22 23:59:59-03:00