【问题标题】:Is there a list of Pytz Timezones?是否有 Pytz 时区列表?
【发布时间】:2012-12-01 18:15:30
【问题描述】:

我想知道 Python 库 pytz 中时区参数的所有可能值。怎么办?

【问题讨论】:

  • 版主说明:请将您的问题保留为问题。相反,您可以在回答帖子中编写自己的解决方案。

标签: python django pytz


【解决方案1】:

您可以使用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

【讨论】:

  • 除了all_timezonespytz also providescommon_timezones
  • 中国为什么不见了?
  • 中国使用single timezone,其时区名称为'Asia/Shanghai'
  • 这个表达式显示了 pytz 可以给出的可怕结果:(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()(结果是 not -28800)。我会避免使用 pytz——dateutil.tz 提供了类似的功能,但使用了 OS 时区数据库并且没有此类问题。
  • @YongweiWu 这是一个错误的API使用。您不应该直接将具有非固定 utc 偏移量的 pytz 时区作为 tzinfo 参数传递。按照 pytz 文档的建议使用 .localize() 方法。
【解决方案2】:

不要创建自己的列表 - 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

【讨论】:

    【解决方案3】:

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

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

    如果您想以编程方式从 zoneinfo 数据库创建此列表,您可以从 zoneinfo 数据库中的 zone.tab 文件编译它。我认为 pytz 没有获取它们的 API,而且我也不认为它很有用。

    【讨论】:

    • 让人们从列表中选择他们的时区非常有用。很多网站和 Linux 安装程序已经这样做了。
    【解决方案4】:

    这里是国家代码、名称、大洲、首都和 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'},
    ]
    

    完整列表: Gist Github

    希望,它会有所帮助。

    【讨论】:

      【解决方案5】:

      编辑:如果您不进一步否决此答案,我将不胜感激。此答案错误,但我宁愿将其保留为历史记录。虽然 pytz 接口是否容易出错是有争议的,但它可以做 dateutil.tz 不能做的事情,尤其是在过去或未来的夏令时方面。我在"Time zones in Python"的文章中诚实地记录了我的经历。


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

      以下代码显示了 pytz 可以给出的问题。当我第一次发现它时,我感到很震惊。 (有趣的是,在 CentOS 7 上 yum 安装的 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 传递给它的localize 方法。

      尽管有他的论点(而且我没有更仔细地阅读 pytz 文档,这很糟糕),但我将保留这个答案。我以一种方式回答了这个问题(如何枚举支持的时区,虽然不是用 pytz),因为我认为 pytz 没有提供正确的解决方案。尽管我的想法是错误的,但这个答案仍然提供了一些信息,恕我直言,这对对此问题感兴趣的人可能有用。 Pytz 的正确 做事方式是违反直觉的。哎呀,如果pytz创建的tzinfo不应该被datetime直接使用,它应该是不同的类型。 pytz 界面设计得很糟糕。 Mark提供的链接显示,不仅仅是我,很多人都被pytz界面误导了。

      【讨论】:

      • 请参阅stackoverflow.com/questions/11473721/… 以获得修复。 pytz 没什么问题,只是你用错了。附言这根本不是问题的答案
      • @MarkRansom 很好的信息,很高兴知道。但是,我不相信你的论点。界面设计错误,句号。这非常违反直觉。
      • 是的,界面设计错了。但错误的是datetime 接口,而不是pytzdatetime 没有预料到 智能 时区对象,所以它的接口没有正确初始化它们。
      • 恕我直言,我不同意。 datetime 是标准 Python 库的一部分,应该遵循 datetime 接口的是 pytz,反之亦然。如果有人可以在没有达成共识的情况下以他们认为更好的方式实现某些接口,那么就不会有强大的软件。
      • 如我所说,pytz 无法跟随datetime 接口,因为datetime 接口有缺陷。该界面的作者没有预料到参数多年来变化的时区问题。仅仅因为它是标准 Python 发行版的一部分并不意味着它是完美的。
      【解决方案6】:

      它们似乎由 here 找到的 tz 数据库时区填充。

      【讨论】:

      • pytz 提供对the tz database 的访问(它是维基百科数据的来源)。
      【解决方案7】:

      可从 Python3.9 获得:

      zoneinfo,Python3.9 中的新模块,适用于 IANA 数据库。 为了获取所有可用的时区,首先:

      pip install tzdata
      

      然后:

      import zoneinfo
      
      print(zoneinfo.available_timezones())
      

      【讨论】:

        【解决方案8】:

        您会在此处找到所有pytz 支持的时区:

        https://gist.github.com/heyalexej/8bf688fd67d7199be4a1682b3eec7568

        【讨论】:

        • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
        【解决方案9】:

        在我看来,这是 pytz 库的设计缺陷。使用偏移量指定时区应该更可靠,例如

        pytz.construct("UTC-07:00")
        

        它为您提供加拿大/太平洋时区。

        【讨论】:

        • 偏移量全年都在变化(通常是因为夏令时),所以这与我们通常认为的时区不同。
        • 所选语法基于tzdata中的定义。
        猜你喜欢
        • 2015-01-03
        • 1970-01-01
        • 2012-06-12
        • 2018-10-20
        • 2019-04-06
        • 2015-01-20
        • 2020-08-26
        • 2018-01-03
        • 2016-02-05
        相关资源
        最近更新 更多