我很好奇如何调用在某些时区选择器上提供的“规范”时区偏移(如果甚至有这样的事情,作为规范偏移,我甚至不确定).
例如,在Windows XP上,您可以看到对于东部时间(美国和加拿大),下拉列表始终显示GMT-05:00这实际上在全年都不正确,因为当夏令时生效时, UTC的偏移量仅为-4:00.另一方面,每个人都提到美国/东方距离UTC 5小时.我想知道如何调用-5:00.电子邮件时间标识符?典型的时区偏移?
另外,如果我用pytz创建美国/东部时区,有没有办法抓住-5:00而不管现在的实际时间是否在夏令时?我的意思是……我想知道是否有一个功能,或者……得到-5:00的东西,无论我今天或8月中旬运行(当DST启用时和实际偏差仅为-4:00)
先感谢您.
解决方法:
如果我们将“规范”表示不在DST中的日期的utcoffset,则问题将减少为查找不是DST的日期(对于每个时区).
我们可以先尝试当前日期.如果不是DST,那么我们很幸运.如果是,那么我们可以单步执行utc转换日期列表(存储在tzone._utc_transition_times中),直到我们找到一个不是DST的日期:
import pytz
import datetime as DT
utcnow = DT.datetime.utcnow()
canonical = dict()
for name in pytz.all_timezones:
tzone = pytz.timezone(name)
try:
dstoffset = tzone.dst(utcnow, is_dst=False)
except TypeError:
# pytz.utc.dst does not have a is_dst keyword argument
dstoffset = tzone.dst(utcnow)
if dstoffset == DT.timedelta(0):
# utcnow happens to be in a non-DST period
canonical[name] = tzone.localize(utcnow, is_dst=False).strftime('%z')
else:
# step through the transition times until we find a non-DST datetime
for transition in tzone._utc_transition_times[::-1]:
dstoffset = tzone.dst(transition, is_dst=False)
if dstoffset == DT.timedelta(0):
canonical[name] = (tzone.localize(transition, is_dst=False)
.strftime('%z'))
break
for name, utcoffset in canonical.iteritems():
print('{} --> {}'.format(name, utcoffset))
# All timezones have been accounted for
assert len(canonical) == len(pytz.all_timezones)
产量
...
Mexico/BajaNorte --> -0800
Africa/Kigali --> +0200
Brazil/West --> -0400
America/Grand_Turk --> -0400
Mexico/BajaSur --> -0700
Canada/Central --> -0600
Africa/Lagos --> +0100
GMT-0 --> +0000
Europe/Sofia --> +0200
Singapore --> +0800
Africa/Tripoli --> +0200
America/Anchorage --> -0900
Pacific/Nauru --> +1200
请注意,上面的代码访问私有属性tzone._utc_transition_times.这是pytz中的实现细节.由于它不是公共API的一部分,因此不保证在未来版本的pytz中存在.实际上,在当前版本的pytz中,它甚至不存在于所有时区中 – 特别是,对于没有DST转换时间的时区,例如“非洲/布琼布拉”,它不存在. (这就是我为什么要先检查utcnow是否恰好在非DST时间段内的原因.)
如果你想要一种不依赖私有属性的方法,我们可以简单地将utcnow返回到有一天,直到我们找到一个非DST时间段的日子.代码会比上面的代码慢一点,但是因为你真的只需要运行一次这段代码来收集所需的信息,所以它真的无关紧要.
以下是不使用_utc_transition_times的代码:
import pytz
import datetime as DT
utcnow = DT.datetime.utcnow()
canonical = dict()
for name in pytz.all_timezones:
tzone = pytz.timezone(name)
try:
dstoffset = tzone.dst(utcnow, is_dst=False)
except TypeError:
# pytz.utc.dst does not have a is_dst keyword argument
dstoffset = tzone.dst(utcnow)
if dstoffset == DT.timedelta(0):
# utcnow happens to be in a non-DST period
canonical[name] = tzone.localize(utcnow, is_dst=False).strftime('%z')
else:
# step through the transition times until we find a non-DST datetime
date = utcnow
while True:
date = date - DT.timedelta(days=1)
dstoffset = tzone.dst(date, is_dst=False)
if dstoffset == DT.timedelta(0):
canonical[name] = (tzone.localize(date, is_dst=False)
.strftime('%z'))
break
for name, utcoffset in canonical.iteritems():
print('{} --> {}'.format(name, utcoffset))
# All timezones have been accounted for
assert len(canonical) == len(pytz.all_timezones)