pytz UTC 转换

Posted

技术标签:

【中文标题】pytz UTC 转换【英文标题】:pytz utc conversion 【发布时间】:2010-11-24 08:52:14 【问题描述】:

将幼稚时间和 tzinfo 转换为 UTC 时间的正确方法是什么? 说我有:

d = datetime(2009, 8, 31, 22, 30, 30)
tz = timezone('US/Pacific')

第一种方式,pytz 启发:

d_tz = tz.normalize(tz.localize(d))
utc = pytz.timezone('UTC')
d_utc = d_tz.astimezone(utc)

第二种方式,来自UTCDateTimeField

def utc_from_localtime(dt, tz):
    dt = dt.replace(tzinfo=tz)
    _dt = tz.normalize(dt)
    if dt.tzinfo != _dt.tzinfo:
        # Houston, we have a problem...
        # find out which one has a dst offset
        if _dt.tzinfo.dst(_dt):
            _dt -= _dt.tzinfo.dst(_dt)
        else:
            _dt += dt.tzinfo.dst(dt)
    return _dt.astimezone(pytz.utc)

不用说,这两种方法在相当多的时区产生不同的结果。

问题是——正确的方法是什么?

【问题讨论】:

我很惊讶没有人从问题正文中删除“谢谢”。让我们看看需要多长时间才能将其移除! 根据我的计算,只有 897 天。 谢谢你,Will,纠正错误! 【参考方案1】:

您的第一种方法似乎是经过批准的方法,并且应该支持 DST。

你可以稍微缩短一点,因为 pytz.utc = pytz.timezone('UTC'),但你已经知道了 :)

tz = timezone('US/Pacific')
def toUTC(d):
    return tz.normalize(tz.localize(d)).astimezone(pytz.utc)

print "Test: ", datetime.datetime.utcnow(), " = ", toUTC(datetime.datetime.now())

【讨论】:

为什么要规范化()?真的有必要吗? @kolypto:显然tz.normalize() 将考虑夏令时和tz.localize() 没有的其他麻烦,如this one 等其他SO 答案中所述。 @kolypto:有些当地时间不存在,例如,在一些国家(北半球)向夏季时间过渡期间,当地时钟在春季向前跳。 tz.localize() 尊重 d 对象(它不会更改时间,它只会尝试添加适当的 tzinfo 对象)因此 tz.normalize() 需要调整不存在的时间。尽管这两个时间(调整之前/之后)都应该对应于相同的 UTC 时间,即,如果我们所做的只是将时间转换为 UTC,那么tz.normalize() 可能是不必要的,就像在这种情况下一样。【参考方案2】:

将朴素时间和 tzinfo 转换为 utc 时间的正确方法是什么?

This answer enumerates some issues with converting a local time to UTC:

from datetime import datetime
import pytz # $ pip install pytz

d = datetime(2009, 8, 31, 22, 30, 30)
tz = pytz.timezone('US/Pacific')

# a) raise exception for non-existent or ambiguous times
aware_d = tz.localize(d, is_dst=None)
## b) assume standard time, adjust non-existent times
#aware_d = tz.normalize(tz.localize(d, is_dst=False))
## c) assume DST is in effect, adjust non-existent times
#aware_d = tz.normalize(tz.localize(naive_d, is_dst=True))

# convert to UTC
utc_d = aware_d.astimezone(pytz.utc)

【讨论】:

我更喜欢这个解决方案,因为它包含有关 DST 选项的详细信息。【参考方案3】:

使用第一种方法。没有理由重新发明时区转换的***

【讨论】:

【参考方案4】:
    import pytz
    from django.utils import timezone

    tz = pytz.timezone('America/Los_Angeles')
    time = tz.normalize(timezone.now())

【讨论】:

不正确。如果USE_TZ=Truetimezone.now() 返回UTC 的感知日期时间,因此您不应该在其上调用tz.normalize()。如果 USE_TZ=False 则 django 使用可能与 America/Los_Angeles 不同的默认时区,并且在这种情况下代码也是错误的。

以上是关于pytz UTC 转换的主要内容,如果未能解决你的问题,请参考以下文章

使用 pytz 将 UTC 转换为其他地方的本地时间

Pytz 在没有 DST 的情况下将时间转换为 UTC

Python pytz:将本地时间转换为 UTC。本地化似乎没有转换

UTC到CST时间转换使用pytz python包

如何在 python 和 django 中使用 Pytz 根据给定的 UTC 偏移量转换数据和时间?

模块pytz:UTC减少而不是增加