【问题标题】:pytz utc conversionpytz UTC 转换
【发布时间】: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,纠正错误!

标签: python datetime utc pytz


【解决方案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 不同的默认时区,并且在这种情况下代码也是错误的。
    猜你喜欢
    • 2020-09-01
    • 2013-06-12
    • 2014-10-05
    • 1970-01-01
    • 2017-03-10
    • 2012-11-01
    • 2018-06-27
    • 2021-08-02
    • 2011-11-19
    相关资源
    最近更新 更多