繁体   English   中英

如何在 Python 中获得人类可读的时区名称?

[英]How can I get a human-readable timezone name in Python?

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

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


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

下面生成一个 defaultdict 映射时区偏移量(例如'-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)

for k, v in result.items():
    print(k, v)

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

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

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

有一个tzlocal模块,它返回一个对应于系统本地时区的pytz tzinfo 对象(在tzlocal 3.0版本之前):

#!/usr/bin/env python
import tzlocal  # $ pip install tzlocal

# display "human-readable" name (tzid)
print(tzlocal.get_localzone_name())

# Example Results:
# -> Europe/Moscow
# -> America/Chicago

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

#!/usr/bin/env python
import time

print(time.strftime('%Z%z'))

# Example Results:
# -> MSK+0300 
# -> CDT-0500

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

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

最初编写此问题时,这可能不存在,但这里有一个获取时区官方名称的片段:

>>> 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 模块站点上查看更多信息。

如果您只想要您所要求的字面意思,“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)

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

查看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'

# 使用 tzlocal 库

from tzlocal import get_localzone

current_timezone = get_localzone()
zone = current_timezone.zone
print(zone)  

使用截至今天 4.1 的最新版本 tzlocal, tzlocal.get_localzone().key会产生以下错误: AttributeError: '_PytzShimTimezone' object has no attribute 'key' 但是tzlocal.get_localzone().zone工作得很好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM