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=True
则timezone.now()
返回UTC 的感知日期时间,因此您不应该在其上调用tz.normalize()
。如果 USE_TZ=False
则 django 使用可能与 America/Los_Angeles 不同的默认时区,并且在这种情况下代码也是错误的。以上是关于pytz UTC 转换的主要内容,如果未能解决你的问题,请参考以下文章
Python pytz:将本地时间转换为 UTC。本地化似乎没有转换