我想知道Python库pytz中timezone参数的所有可能值是什么。怎么做呢?


当前回答

不要创建自己的列表- pytz有一个内置的集合:

import pytz
set(pytz.all_timezones_set)  
>>> {'Europe/Vienna', 'America/New_York', 'America/Argentina/Salta',..}

然后你可以应用一个时区:

import datetime
tz = pytz.timezone('Pacific/Johnston')
ct = datetime.datetime.now(tz=tz)
>>> ct.isoformat()
2017-01-13T11:29:22.601991-05:00

或者如果你已经有一个datetime对象是TZ感知的(不是天真的):

# This timestamp is in UTC
my_ct = datetime.datetime.now(tz=pytz.UTC)

# Now convert it to another timezone
new_ct = my_ct.astimezone(tz)
>>> new_ct.isoformat()
2017-01-13T11:29:22.601991-05:00

其他回答

编辑:如果你不要再对这个答案投反对票,我会很感激的。这个答案是错误的,但我宁愿保留它作为一个历史注释。虽然pytz接口是否容易出错是有争议的,但它可以做一些dateutil的事情。Tz做不到,特别是关于过去或将来的夏令时。我在一篇文章“Python中的时区”中诚实地记录了我的经验。


如果您使用的是类unix平台,我建议您避免使用pytz,只查看/usr/share/zoneinfo。dateutil。Tz可以利用那里的信息。

下面的代码段显示了pytz可能给出的问题。当我第一次发现时,我很震惊。(有趣的是,yum在CentOS 7上安装的pytz没有出现这个问题。)

import pytz
import dateutil.tz
from datetime import datetime
print((datetime(2017,2,13,14,29,29, tzinfo=pytz.timezone('Asia/Shanghai'))
     - datetime(2017,2,13,14,29,29, tzinfo=pytz.timezone('UTC')))
     .total_seconds())
print((datetime(2017,2,13,14,29,29, tzinfo=dateutil.tz.gettz('Asia/Shanghai'))
     - datetime(2017,2,13,14,29,29, tzinfo=dateutil.tz.tzutc()))
     .total_seconds())

-29160.0
-28800.0

也就是说,pytz创建的时区是真实的本地时间,而不是人们所观察的标准本地时间。上海符合+0800,而不是pytz建议的+0806:

pytz.timezone('Asia/Shanghai')
<DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>

编辑:感谢Mark Ransom的评论和反对票,现在我知道我使用pytz的方式是错误的。总之,您不应该将pytz.timezone(…)的结果传递给datetime,而应该将datetime传递给它的本地化方法。

Despite his argument (and my bad for not reading the pytz documentation more carefully), I am going to keep this answer. I was answering the question in one way (how to enumerate the supported timezones, though not with pytz), because I believed pytz did not provide a correct solution. Though my belief was wrong, this answer is still providing some information, IMHO, which is potentially useful to people interested in this question. Pytz's correct way of doing things is counter-intuitive. Heck, if the tzinfo created by pytz should not be directly used by datetime, it should be a different type. The pytz interface is simply badly designed. The link provided by Mark shows that many people, not just me, have been misled by the pytz interface.

下面是一个包含国家代码、名称、大洲、首都和pytz时区的Python列表:

countries = [
  {'timezones': ['Europe/Paris'], 'code': 'FR', 'continent': 'Europe', 'name': 'France', 'capital': 'Paris'}
  {'timezones': ['Africa/Kampala'], 'code': 'UG', 'continent': 'Africa', 'name': 'Uganda', 'capital': 'Kampala'},
  {'timezones': ['Asia/Colombo'], 'code': 'LK', 'continent': 'Asia', 'name': 'Sri Lanka', 'capital': 'Sri Jayewardenepura Kotte'},
  {'timezones': ['Asia/Riyadh'], 'code': 'SA', 'continent': 'Asia', 'name': 'Saudi Arabia', 'capital': 'Riyadh'},
  {'timezones': ['Africa/Luanda'], 'code': 'AO', 'continent': 'Africa', 'name': 'Angola', 'capital': 'Luanda'},    
  {'timezones': ['Europe/Vienna'], 'code': 'AT', 'continent': 'Europe', 'name': 'Austria', 'capital': 'Vienna'},
  {'timezones': ['Asia/Calcutta'], 'code': 'IN', 'continent': 'Asia', 'name': 'India', 'capital': 'New Delhi'},
  {'timezones': ['Asia/Dubai'], 'code': 'AE', 'continent': 'Asia', 'name': 'United Arab Emirates', 'capital': 'Abu Dhabi'},
  {'timezones': ['Europe/London'], 'code': 'GB', 'continent': 'Europe', 'name': 'United Kingdom', 'capital': 'London'},
]

要获得完整的列表,请参阅GitHub Gist。

时区名称是指定时区的唯一可靠方式。

您可以在这里找到时区名称列表:http://en.wikipedia.org/wiki/List_of_tz_database_time_zones 请注意,该列表包含许多别名,例如时区的US/Eastern正确地称为America/New_York。

如果您希望通过编程方式从zoneinfo数据库创建此列表,则可以从zone编译它。zoneinfo数据库中的TAB文件。我不认为pytz有一个API来获取它们,而且我也不认为它会非常有用。

你可以用pytz.all_timezones列出所有可用的时区:

In [40]: import pytz
In [41]: pytz.all_timezones
Out[42]: 
['Africa/Abidjan',
 'Africa/Accra',
 'Africa/Addis_Ababa',
 ...]

还有pytz.common_timezones:

In [45]: len(pytz.common_timezones)
Out[45]: 403

In [46]: len(pytz.all_timezones)
Out[46]: 563

不要创建自己的列表- pytz有一个内置的集合:

import pytz
set(pytz.all_timezones_set)  
>>> {'Europe/Vienna', 'America/New_York', 'America/Argentina/Salta',..}

然后你可以应用一个时区:

import datetime
tz = pytz.timezone('Pacific/Johnston')
ct = datetime.datetime.now(tz=tz)
>>> ct.isoformat()
2017-01-13T11:29:22.601991-05:00

或者如果你已经有一个datetime对象是TZ感知的(不是天真的):

# This timestamp is in UTC
my_ct = datetime.datetime.now(tz=pytz.UTC)

# Now convert it to another timezone
new_ct = my_ct.astimezone(tz)
>>> new_ct.isoformat()
2017-01-13T11:29:22.601991-05:00