为什么pytz正确地调整时间&在穿越TZ& DST边界,但不是TZ名称? [英] Why does pytz correctly adjust time & offset when crossing TZ & DST boundaries but not the TZ name?

查看:180
本文介绍了为什么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%s\\\
%('Chicago',
chicagoDT.strftime(%Y /%m /%d%H:%M:%S% Z'z),
chicagoDT.dst()))

tzTups = [('New York','America / New_York'),
('London' '欧洲/伦敦'),
('悉尼','澳大利亚/悉尼')]

for tz ttTups中的Tup:
tz = pytz.timezone(tzTup [1])$ ​​b $ b locDT = tz.normalize(chicagoDT.astimezone(tz))
sys.stdout.write(%-10s %-35s%s\\\
%(tzTup [0],
locDT.strftime(%Y /%m /%d%H:%M:%S%Z%z),
locDT.dst()))

以下是输出:

 芝加哥2014/03/12 14:34:53 CDT -0500 1:00:00 
纽约2014/03/12 15:34: 53 EDT -0400 1:00:00
伦敦2014/03/12 19:34:53 GMT +0000 0:00:00
悉尼2014/03/13 06:34:53 EST +1100 1:00:00

使用 timeanddate.com ,我们看到所有这些信息是正确的,包括悉尼时间,偏移量和 1:00:00 表示 datetime 对象认为DST目前处于有效状态



唯一的问题是悉尼时间标有 EST 而不是 EDT 。事实上,即使知道DST偏移量,我也不能让Python在 EDT 中声明悉尼:

  tz = pytz.timezone('澳大利亚/悉尼')
在范围(1,13)中:
locDT = tz.normalize(tz.localize (datetime.datetime(2013,i,15)))
sys.stdout.write(%02d%s%s\\\
%(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 或我可能没有的Olson DB中,这是一个已知问题吗? (Mine说使用 OLSON_VERSION ='2010b'。)

解决方案

IANA 维护Olson数据库。在IANA的tz 邮件列表(讨论跨越两个月: 2013年3月 2013年4月 )。



所有方面似乎有强烈的意见,缩写应该是什么,强烈的意见导致了僵局。



有人说这些缩写是过去的遗迹,不应该被使用,而且不应该修正歧义,以帮助阻止其使用。



显然没有认可澳大利亚的权力界定了缩写。 有人说冲突的组织使用不同的时区缩写,所以不要选择政治方面,IANA选择EST进行标准和夏令时。



现在,Olson数据库在澳大利亚/悉尼的所有日期使用所有时区的EST

 在[60]中:import pytz 
在[61]中:sydney = pytz.timezone('澳大利亚/悉尼')

在[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,13,16,0) EST'),
(datetime.datetime(1942,3,28,15,0),'EST'),
(datetime.datetime(1942,9,26,16,0) EST'),
(datetime.datetim e(1943,3,27,15,0),'EST'),
...]

在[69]中:set([tzabbrev for utcoffset,dstoffset,tzabbrev in sydney._transition_info])
输出[69]:{'EST'}

在澳大利亚/悉尼时区,EST跨越每个过渡边界。


I have reviewed several pytz-related questions here, but none seems to address the exact problem I'm seeing.

Following the pytz documentation, here's a loop to print the current time in multiple time zones, including time zone offset, time zone name, and whether the datetime object thinks it's DST.

nowDT = datetime.datetime.now()
chicagoTz = pytz.timezone('America/Chicago')
chicagoDT = chicagoTz.normalize(chicagoTz.localize(nowDT))
sys.stdout.write( "%-10s %-35s %s\n" % ('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 %s\n" % (tzTup[0],
                                            locDT.strftime("%Y/%m/%d %H:%M:%S %Z %z"),
                                            locDT.dst()) )

Here's the output:

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

Checking with, say, timeanddate.com, we see that all of this information is correct, including the Sydney time, offset, and the 1:00:00 indicating that the datetime object believes that DST is currently in effect in Sydney.

The only problem is that the Sydney time is labeled EST instead of EDT. In fact, I can't get Python to ever declare Sydney in EDT even though it knows about the DST offset:

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 %s\n" % (i, locDT.dst(), locDT.tzname()))

Output:

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

Am I doing something wrong? Is /usr/share/zoneinfo out of date on my system? Is this a known issue corrected in recent versions of pytz or the Olson DB that I might not have? (Mine says it's using OLSON_VERSION = '2010b'.)

解决方案

The IANA maintains the Olson database. The question of what timezone abbreviation(s) should be used for Australia was discussed in the IANA's tz mailing list here (the discussion spanned two months: March 2013, April 2013).

There seems to be strong opinion on all sides as to what the abbreviations should be and those strong opinions have resulted in gridlock.

Some say the abbreviations are a relic of the past and should not be used and the ambiguity should not be fixed to help discourage its use.

Apparently there is no recognized authority in Australia defining the abbreviations. Some say conflicting organizations use different timezone abbreviations, and so as not to pick political sides, the IANA chose EST for both standard and daylight savings times.

For now, the Olson DB uses EST for all timezones for all dates in Australia/Sydney:

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'}

This shows that in the Australia/Sydney timezone, EST is used across every transition boundary.

这篇关于为什么pytz正确地调整时间&在穿越TZ& DST边界,但不是TZ名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆