为什么pytz在跨越TZ和DST边界时正确调整时间和偏移量,而不是TZ名称?



我在这里回顾了几个与pytz相关的问题,但似乎没有一个能解决我所看到的确切问题。

在pytz文档之后,这里是一个循环,用于打印多个时区的当前时间,包括时区偏移量,时区名称,以及datetime对象是否认为它是DST。

nowDT = datetime.datetime.now()
chicagoTz = pytz.timezone('America/Chicago')
chicagoDT = chicagoTz.normalize(chicagoTz.localize(nowDT))
sys.stdout.write( "%-10s %-35s %sn" % ('Chicago',
                                        chicagoDT.strftime("%Y/%m/%d %H:%M:%S %Z %z"),
                                        chicagoDT.dst()) )
tzTups = [('New York', 'America/New_York'),
          ('London',   'Europe/London'),
          ('Sydney',   'Australia/Sydney')]
for tzTup in tzTups:
    tz = pytz.timezone(tzTup[1])
    locDT = tz.normalize(chicagoDT.astimezone(tz))
    sys.stdout.write( "%-10s %-35s %sn" % (tzTup[0],
                                            locDT.strftime("%Y/%m/%d %H:%M:%S %Z %z"),
                                            locDT.dst()) )

输出如下:

Chicago    2014/03/12 14:34:53 CDT -0500       1:00:00
New York   2014/03/12 15:34:53 EDT -0400       1:00:00
London     2014/03/12 19:34:53 GMT +0000       0:00:00
Sydney     2014/03/13 06:34:53 EST +1100       1:00:00

通过timeanddate.com检查,我们看到所有这些信息都是正确的,包括悉尼时间、偏移量和表明datetime对象认为夏令时目前在悉尼生效的1:00:00

唯一的问题是悉尼时间被标记为EST而不是EDT。事实上,我无法让Python在EDT中声明Sydney,即使它知道DST偏移量:

tz = pytz.timezone('Australia/Sydney')
for i in range(1,13):
    locDT = tz.normalize(tz.localize(datetime.datetime(2013, i, 15)))
    sys.stdout.write("%02d %s %sn" % (i, locDT.dst(), locDT.tzname()))
输出:

01 1:00:00 EST
02 1:00:00 EST
03 1:00:00 EST
04 0:00:00 EST
05 0:00:00 EST
06 0:00:00 EST
07 0:00:00 EST
08 0:00:00 EST
09 0:00:00 EST
10 1:00:00 EST
11 1:00:00 EST
12 1:00:00 EST

我做错了什么吗?/usr/share/zoneinfo在我的系统上过时了吗?这是一个已知的问题,在pytz的最新版本或奥尔森DB,我可能没有纠正?(我的显示是使用OLSON_VERSION = '2010b')

IANA维护Olson数据库。关于澳大利亚应该使用哪个时区缩写的问题在IANA的tz邮件列表中进行了讨论(讨论持续了两个月:2013年3月和2013年4月)。

关于应该使用什么缩写,似乎各方意见都很强烈,而这些强烈的意见导致了僵局。

一些人说这些缩写是过去的遗物,不应该被使用,不应该修复歧义来阻止它的使用。

显然,在澳大利亚没有公认的权威机构定义缩写。有人说,冲突的组织使用不同的时区缩写,为了不偏袒政治立场,IANA选择了EST作为标准时间和夏令时。

目前,Olson DB对澳大利亚/悉尼所有日期的所有时区使用EST:

In [60]: import pytz
In [61]: sydney = pytz.timezone('Australia/Sydney')
In [68]: [(date, tzabbrev) for date, (utcoffset, dstoffset, tzabbrev) in zip(sydney._utc_transition_times, sydney._transition_info)]
Out[68]: 
[(datetime.datetime(1, 1, 1, 0, 0), 'EST'),
 (datetime.datetime(1916, 12, 31, 14, 1), 'EST'),
 (datetime.datetime(1917, 3, 24, 15, 0), 'EST'),
 (datetime.datetime(1941, 12, 31, 16, 0), 'EST'),
 (datetime.datetime(1942, 3, 28, 15, 0), 'EST'),
 (datetime.datetime(1942, 9, 26, 16, 0), 'EST'),
 (datetime.datetime(1943, 3, 27, 15, 0), 'EST'),
 ...]
In [69]: set([tzabbrev for utcoffset, dstoffset, tzabbrev in sydney._transition_info])
Out[69]: {'EST'}

这表明在澳大利亚/悉尼时区,EST在每个转换边界上使用。

相关内容

  • 没有找到相关文章

最新更新