python – Django make_aware用法

Django docs说:

The pytz.NonExistentTimeError exception is raised if you try to make
value aware during a DST transition such that the time never occurred
(when entering into DST). Setting is_dst to True or False will avoid
the exception by moving the hour backwards or forwards by 1
respectively. For example, is_dst=True would change a non-existent
time of 2:30 to 1:30 and is_dst=False would change the time to 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

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

最佳答案 从
source code我们可以看到Django只是包装pytz.因此,如果这里存在问题,则可能是pytz错误或Django文档错误.

现在,由于你传递localize()一个不存在的时间,它将不得不改变挂钟时间或tzinfo以返回有效时间.虽然pytz documentation在这一点上不是很精确,但似乎它的合同总是返回一个日期时间,其时间与传入的时间相同.这是有道理的,特别是当你考虑一个模糊的平行情况时时间.

所以我认为Django文档在说:

Setting is_dst to True or False will avoid the exception by moving the hour backwards or forwards by 1 respectively. For example, is_dst=True would change a non-existent time of 2:30 to 1:30 and is_dst=False would change the time to 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

关于这个请考虑filing a ticket

点赞