python - 为什么 django.utils.timezone.make_aware 和 pytz.localize 在处理 DST 时返回不同的结果?

标签 python django datetime timezone pytz

我正在使用 django 1.11 和 pytz 2018.6

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

我的主要问题是在 America/Sao_Paulo 时区中本地化日期 2018-11-04 00:00:00。根据最新的 pytz 版本,这是 2018 年该时区开始夏令时的日期。

好吧,在我的应用程序中,当我尝试本地化提到的日期时,我开始看到 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 进行本地化,我会得到不同的结果:

sp.localize(dst_start_date) # Returns 2018-11-04 00:00:00-03:00

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

这让我感到困惑,因为阅读 django.utils.timezone 中的 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 日期发生了变化。

最佳答案

区别在于传递给localizeis_dst参数。当您自己调用它但将其关闭时,它默认为 False。在您发布的 make_aware 代码中,它默认为 None

关于python - 为什么 django.utils.timezone.make_aware 和 pytz.localize 在处理 DST 时返回不同的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52997920/

相关文章:

python - Pyenv virtualenv 没有激活,尝试了我所知道的一切

python - 导入错误: cannot import name 'ft2font' from partially initialized module 'matplotlib'

python - 使用 PyQt 在图像上画线

Django - 显示记录表的总和

python - Django:保存腌制对象

django - 来自 Django 外键字段的大量查询

django - 覆盖 Django REST Frameworks 更新方法以保存嵌套的序列化程序

datetime - 如何在 Julia 中创建高分辨率时间序列图

python - Pandas - 计算过去 x 天数的值频率

java - ResultSet#getDate() 语义