【问题标题】:How can I get a human-readable timezone name in Python?如何在 Python 中获得人类可读的时区名称?
【发布时间】:2011-03-30 04:27:21
【问题描述】:

在我正在处理的 Python 项目中,我希望能够获得与系统本地时区相对应的 America/New_York 形式的“人类可读”时区名称, 显示给用户。我见过的每段访问时区信息的代码都只返回一个数字偏移量(-0400)或一个字母代码(EDT),或者有时两者都返回。是否有一些 Python 库可以访问此信息,或者如果没有,将偏移量/字母代码转换为人类可读的名称?

如果有多个与特定时区对应的人类可读名称,则可能的结果列表或其中任何一个都可以,如果没有与当前时区相对应的人类可读名称,我' 将采取异常或None[] 或其他任何方式。


澄清:我不记得我最初写这个问题时的确切想法,但我认为我真正想要的是一种将时区变成人类可读的方法姓名。我不认为这个问题是为了专注于如何专门获取系统本地时区,但对于我想到的特定用例,恰好本地时区是我想要的名称。我不会编辑有关本地时区的内容,因为有两个方面的答案。

【问题讨论】:

  • 我认为你确实需要小心你如何使用它。举个例子:当我们在 2010 年 10 月在欧洲/罗马从 CEST 切换到 CET 时,2010-10-31T02:30:00CEST2010-10-31T02:30:00CET 都被记录了,一个相当于 2010-10-31T00:30:00UTC,另一个相当于 2010-10-31T01:30:00UTC2010-10-31T02:30:00 Europe/Rome 会模棱两可。

标签: python timezone


【解决方案1】:

http://pytz.sourceforge.net/ 可能会有所帮助。如果不出意外,您也许可以获取所有时区的列表,然后遍历,直到找到与您的偏移量匹配的时区。

【讨论】:

  • 迭代不是一个坏主意。我会遍历所有这些并构建一个shelve 文件,或者只是将dict 存储在一个模块中或由字母代码键入的东西中。然后,您可以将dict 与应用程序一起发送,而不必执行两次搜索。在这种情况下,您甚至不必发送 pytz:您可以在构建 dict 的脚本中使用它
  • 是的。只需预先计算(甚至只是在启动时构建它;如果您每次执行只执行一次,它就不会花费那么长时间)。
  • 没那么简单——当前与 UTC 的偏移量不足以确定我所在的时区。例如,America/Denver 和 America/Phoenix 在冬天但夏天不同的偏移量。这很常见。
【解决方案2】:

查看python-dateutil

py> from dateutil.tz import *
py> ny = gettz('America/New York')
py> ny._filename
'/usr/share/zoneinfo/America/New_York'
py> ny._filename.split('/', 4)[-1]
'America/New_York'

【讨论】:

  • 但是,如果我有一个不是从 dateutil.tz.gettz 获得的 tzinfo 对象 - 例如,来自 pytz 的一个对象 - 或者如果我只是调用 gettz() (在这种情况下,文件名是/etc/localtime)。 (我仍然很欣赏这些信息)
  • 那么,这些时区对象来自哪里?您可以存储时区的名称——gettz 的字符串参数——并使用该参数和gettz 重构时区。我想我假设某些用例,例如在数据库中存储时间和相关的时区字符串。我永远不会单独使用gettz 来获取本地时区,但在我的情况下,用户也是网络浏览器背后的人。
【解决方案3】:

以下生成一个默认字典,将时区偏移量(例如“-0400”)和缩写(例如“EDT”)映射到常见的地理时区名称(例如“America/New_York”)。

import os
import dateutil.tz as dtz
import pytz
import datetime as dt
import collections

result=collections.defaultdict(list)
for name in pytz.common_timezones:
    timezone=dtz.gettz(name)
    now=dt.datetime.now(timezone)
    offset=now.strftime('%z')
    abbrev=now.strftime('%Z')
    result[offset].append(name)
    result[abbrev].append(name)    
print(result)

请注意,时区缩写可以有vastly different meanings。例如,“EST”可以代表澳大利亚的东部夏令时间 (UTC+10),或北美的东部标准时间 (UTC-5)。

此外,对于使用夏令时标准时间的地区,偏移量和缩写可能会有所变化。因此,保存静态字典可能无法提供一年 365 天的正确时区名称。

【讨论】:

  • now.strftime('%Z') 确实是我一直在寻找的答案。这是假设不使用任何可能模棱两可的时区名称(例如 EST)。此外,对于任何需要它的人,有一个pytz timezone names 的列表。
【解决方案4】:

如果您只想要您所要求的字面意思,“America/New_York 形式的时区名称,对应于系统本地时区”,并且如果您只关心 Linux(和类似的),那么这应该可以完成工作:

import os
import os.path
import sys 

def main(argv):
  tzname = os.environ.get('TZ')
  if tzname:
    print tzname
  elif os.path.exists('/etc/timezone'):
    print file('/etc/timezone').read()
  else:
    sys.exit(1)

if __name__ == '__main__':
  main(sys.argv)

当然,最好有一个库以更简洁的方式封装它,并且可能处理您在 cmets 中提到的其他情况,例如已经拥有 tzinfo 对象。我认为您可以使用 Amber 提到的 pytz 来做到这一点,但对我来说,具体方法并不明显......

【讨论】:

    【解决方案5】:

    我希望能够获得一个“人类可读”的时区名称,格式为 America/New_York,对应于系统本地时区,以显示给用户。

    tzlocal module返回对应系统本地时区的pytztzinfo对象(tzlocal 3.0之前的版本):

    #!/usr/bin/env python
    import tzlocal  # $ pip install tzlocal
    
    print(tzlocal.get_localzone().zone) # display "human-readable" name (tzid)
    # -> Europe/Moscow
    

    要回答标题中的问题(来自 google 的人),您可以使用%Z%z 打印本地时区信息:

    #!/usr/bin/env python
    import time
    
    print(time.strftime('%Z%z'))
    # -> MSK+0300
    

    它打印当前时区缩写和与您当地时区相对应的 utc 偏移量。

    【讨论】:

    • 从今天起tzlocal.get_localzone().zone改为tzlocal.get_localzone().key
    • @smm 谢谢。我添加了一个兼容性说明(答案对 tzlocal
    【解决方案6】:

    这个问题最初写的时候可能没有,但是这里有一个sn-p来获得时区官方指定:

    >>> eastern = timezone('US/Eastern')
    >>> eastern.zone
    'US/Eastern'
    

    此外,这可以与非天真的日期时间对象一起使用(也就是使用pytz.<timezone>.localize(<datetime_object>)datetime_object.astimezone(pytz.<timezone>) 设置实际时区的日期时间,如下所示:

    >>> import datetime, pytz
    >>> todaynow = datetime.datetime.now(tz=pytz.timezone('US/Hawaii'))
    >>> todaynow.tzinfo # turned into a string, it can be split/parsed
    <DstTzInfo 'US/Hawaii' HST-1 day, 14:00:00 STD>
    >>> todaynow.strftime("%Z")
    'HST'
    >>> todaynow.tzinfo.zone
    'US/Hawaii'
    

    这当然是为了教育那些登陆这里的搜索引擎用户。 ...在pytz module site 上查看更多信息。

    【讨论】:

    • 我认为提及这一点会很有用 - 假设确实如此 - 这是一个 pytz 特性,而不是所有时区对象的固有特性。
    【解决方案7】:

    # 使用 tzlocal 库

    from tzlocal import get_localzone
    
    current_timezone = get_localzone()
    zone = current_timezone.zone
    print(zone)  
    

    【讨论】:

      猜你喜欢
      • 2017-12-01
      • 1970-01-01
      • 2012-09-03
      • 2023-03-20
      • 2013-09-22
      • 1970-01-01
      • 2020-01-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多