Django make_aware 用法

And*_*pos 10 python django

Django 文档说:

pytz.NonExistentTimeError,如果你试图让异常引发 value一个DST过渡,以使时间从未发生过(进入DST时)期间认识。设置is_dstTrueorFalse将通过分别将小时向后或向前移动 1来避免异常。例如,is_dst=True将不存在的时间 2:30is_dst=False更改为 1:30,并将时间更改为 3:30。

所以我希望时间根据 的值向前或向后移动一个is_dst

但是根据我的测试,时区正在改变,而不是时间。我误解了 Django 文档还是这是一个错误?

我测试了以下内容:

import pytz
import datetime
from django.utils.timezone import make_aware

tz = pytz.timezone('America/Sao_Paulo')
dt = datetime.datetime(2017, 10, 15 ,0 ,0)
print(make_aware(dt, tz))        # NonExistentTimeError
print(make_aware(dt, tz, True))  # 2017-10-15 00:00:00-02:00
print(make_aware(dt, tz, False)) # 2017-10-15 00:00:00-03:00
Run Code Online (Sandbox Code Playgroud)

2017-10-15 是 DST 将在该America/Sao_Paulo时区开始的时间,因此当时钟到达 00:00 时,它应该跳到 01:00。该make_aware方法返回的日期时间不存在。

Kev*_*nry 5

源码中我们可以看到Django只是对pytz进行了包装。因此,如果这里出现问题,要么是 pytz bug,要么是 Django 文档 bug。

现在,由于您正在经过localize()一个不存在的时间,因此必须更改挂钟时间或返回tzinfo有效时间。尽管pytz 文档在这一点上不是很精确,但它的合同似乎是始终返回datetime与传入的时钟时间相同的挂钟时间。这是有道理的,特别是当您考虑不明确的并行情况时时间。

所以我认为 Django 文档中有错误:

设置is_dstTrueFalse将通过将小时分别向后或向前移动 1 来避免异常。例如,is_dst=True将不存在的时间 2:30 更改为 1:30,is_dst=False并将时间更改为 3:30。

但请注意,实际时刻与文档描述的相同:

tz = pytz.timezone('America/Sao_Paulo')
dt = datetime.datetime(2017, 10, 15, 0)
dt_plus_one = datetime.datetime(2017, 10, 15, 1)
dt_minus_one = datetime.datetime(2017, 10, 14, 23)

make_aware(dt, tz, True) == make_aware(dt_minus_one, tz)  # True
make_aware(dt, tz, False) == make_aware(dt_plus_one, tz)  # True
Run Code Online (Sandbox Code Playgroud)

请考虑就此提交罚单!