为什么是Django.utils.timezone.让你意识到并pytz.本地化在处理DST时返回不同的结果?

2024-04-24 06:07:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用的是django 1.11和pytz 2018.6

我在理解django如何处理DST时遇到了一些问题。在

我的主要问题是在America/Sao_Paulo时区中定位日期2018-11-04 00:00:00。根据最新的pytz版本,这是2018年DST在这个时区开始的日期。在

嗯,在我的应用程序中,当我试图本地化所提到的日期时,我开始看到pytz.exceptions.NonExistentTimeError异常。以下代码重现了此异常:

import os
import datetime
import django
import pytz
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")
django.setup()
from django.utils.timezone import make_aware

sp = pytz.timezone('America/Sao_Paulo')
dst_start_date = datetime.datetime(2018, 11, 4, 0, 0, 0)
make_aware(dst_start_date, sp)
# Exception raised: pytz.exceptions.NonExistentTimeError: 2018-11-04 00:00:00

但是,如果我尝试使用pytz.localize而不是make_aware进行本地化,则会得到不同的结果:

^{pr2}$

我希望在尝试本地化时也能收到同样的异常。但它并没有引发异常,实际上返回了一个错误的结果(-03:00偏移量是我们不在DST上的时候。在特定的日期,我希望2018-11-04 00:00:00-03:00日期转换为2018-11-04 00:00:00-02:00)。在

这让我很困惑,因为阅读make_aware中的make_aware代码时,我明白了调用相同的pytz.tzinfo.localize方法。在

# django.utils.timezone
def make_aware(value, timezone=None, is_dst=None):
    """
    Makes a naive datetime.datetime in a given time zone aware.
    """
    if timezone is None:
        timezone = get_current_timezone()
    if hasattr(timezone, 'localize'):
        # This method is available for pytz time zones.
        return timezone.localize(value, is_dst=is_dst)
    else:
        # Check that we won't overwrite the timezone of an aware datetime.
        if is_aware(value):
            raise ValueError(
                "make_aware expects a naive datetime, got %s" % value)
        # This may be wrong around DST changes!
        return value.replace(tzinfo=timezone)

为什么这两个结果不同?为什么我在手动尝试将日期2018-11-04 00:00:00本地化为America/Sao_Paulo时没有得到异常?在

在尝试此代码之前,请确保您拥有最新的pytz版本(pip install pytz --upgrade),因为我们今年的DST日期有所更改。在


Tags: djangoimportdatetimemakeisvaluedstsao