简体   繁体   English

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

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

In a Python project I'm working on, I'd like to be able to get a "human-readable" timezone name of the form America/New_York , corresponding to the system local timezone, to display to the user.在我正在处理的 Python 项目中,我希望能够获得一个America/New_York形式的“人类可读”时区名称,对应于系统本地时区,以显示给用户。 Every piece of code I've seen that accesses timezone information only returns either a numeric offset (-0400) or a letter code (EDT) or sometimes both.我见过的每段访问时区信息的代码都只返回一个数字偏移量(-0400)或一个字母代码(EDT),或者有时两者都返回。 Is there some Python library that can access this information, or if not that, convert the offset/letter code into a human-readable name?是否有一些 Python 库可以访问此信息,或者如果没有,将偏移量/字母代码转换为人类可读的名称?

If there's more than one human-readable name corresponding to a particular timezone, either a list of the possible results or any one of them is fine, and if there is no human-readable name corresponding to the current time zone, I'll take either an exception or None or [] or whatever.如果有多个与特定时区相对应的人类可读名称,则可能的结果列表或其中任何一个都可以,如果没有与当前时区相对应的人类可读名称,我会采取异常或None[]或其他。


A clarification: I don't remember exactly what I had in mind when I originally wrote this question, but I think what I really wanted was a way to turn a timezone into a human-readable name.澄清一下:我不记得我最初写这个问题时的确切想法,但我认为我真正想要的是一种将时区变成人类可读名称的方法。 I don't think this question was meant to focus on how to get the system local timezone specifically, but for the specific use case I had in mind, it just happened that the local timezone was the one I wanted the name for.我不认为这个问题是为了专注于如何专门获取系统本地时区,但对于我想到的特定用例,恰好本地时区是我想要的名称。 I'm not editing the bit about the local timezone out of the question because there are answers focusing on both aspects.我没有编辑有关本地时区的问题,因为有两个方面的答案。

The following generates a defaultdict mapping timezone offsets (eg '-0400') and abbreviations (eg 'EDT') to common geographic timezone names (eg 'America/New_York').下面生成一个 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)

Note that timezone abbreviations can have vastly different meanings .请注意,时区缩写可以有非常不同的含义 For example, 'EST' could stand for Eastern Summer Time (UTC+10) in Australia, or Eastern Standard Time (UTC-5) in North America.例如,“EST”可以代表澳大利亚的东部夏令时间 (UTC+10),或北美的东部标准时间 (UTC-5)。

Also, the offsets and abbreviations may change for regions that use daylight standard time.此外,对于使用日光标准时间的地区,偏移量和缩写可能会发生变化。 So saving the static dict may not provide the correct timezone name 365 days a year.因此,保存静态字典可能无法一年 365 天提供正确的时区名称。

I'd like to be able to get a "human-readable" timezone name of the form America/New_York, corresponding to the system local timezone, to display to the user.我希望能够获得与系统本地时区相对应的 America/New_York 形式的“人类可读”时区名称,以显示给用户。

There is tzlocal module that returns a pytz tzinfo object (before tzlocal 3.0 version) that corresponds to the system local timezone:有一个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

To answer the question in the title (for people from google), you could use %Z%z to print the local time zone info:要回答标题中的问题(针对来自 google 的人),您可以使用%Z%z打印本地时区信息:

#!/usr/bin/env python
import time

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

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

It prints the current timezone abbreviation and the utc offset corresponding to your local timezone.它打印当前时区缩写和与您当地时区相对应的 utc 偏移量。

http://pytz.sourceforge.net/ may be of help. http://pytz.sourceforge.net/可能会有所帮助。 If nothing else, you may be able to grab a list of all of the timezones and then iterate through until you find one that matches your offset.如果不出意外,您也许可以获取所有时区的列表,然后遍历,直到找到与您的偏移量匹配的时区。

This may not have been around when this question was originally written, but here is a snippet to get the time zone official designation:最初编写此问题时,这可能不存在,但这里有一个获取时区官方名称的片段:

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

Further, this can be used with a non-naive datetime object (aka a datetime where the actual timezone has been set using pytz.<timezone>.localize(<datetime_object>) or datetime_object.astimezone(pytz.<timezone>) as follows:此外,这可以与非天真的日期时间对象(也就是使用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'

This is, of course, for the edification of those search engine users who landed here.这当然是为了教育那些登陆这里的搜索引擎用户。 ... See more at the pytz module site . ...在pytz 模块站点上查看更多信息。

If you want only literally what you asked for, "the timezone name of the form America/New_York, corresponding to the system local timezone", and if you only care about Linux (and similar), then this should do the job:如果您只想要您所要求的字面意思,“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)

Of course it would be nicer to have a library that encapsulates this in a cleaner way, and that perhaps handles the other cases you mention in comments like already having a tzinfo object.当然,拥有一个以更简洁的方式封装它的库会更好,并且可能会处理您在评论中提到的其他情况,例如已经拥有tzinfo对象。 I think you can do that with pytz mentioned by Amber but it's not obvious to me just how...我认为您可以使用 Amber 提到的pytz来做到这一点,但对我来说这并不明显......

Check out python-dateutil查看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'

# use tzlocal library # 使用 tzlocal 库

from tzlocal import get_localzone

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

Working with the latest version of tzlocal which is 4.1 as of today, tzlocal.get_localzone().key produces the following error: AttributeError: '_PytzShimTimezone' object has no attribute 'key' .使用截至今天 4.1 的最新版本 tzlocal, tzlocal.get_localzone().key会产生以下错误: AttributeError: '_PytzShimTimezone' object has no attribute 'key' But tzlocal.get_localzone().zone works lovely.但是tzlocal.get_localzone().zone工作得很好。

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

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