首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python:给定Timezone名称的所有可能的Timezone缩写(反之亦然)

Python:给定Timezone名称的所有可能的Timezone缩写(反之亦然)
EN

Stack Overflow用户
提问于 2016-03-17 17:23:52
回答 5查看 14.7K关注 0票数 9

使用pytz,我知道如何获得一个Timezone名称的列表,但我希望获得每个Timezone名称的所有可能的Timezone缩写:

代码语言:javascript
运行
复制
import pytz
list(pytz.common_timezones)
['Africa/Abidjan', 'Africa/Accra', 'Africa/Addis_Ababa',...]

我正在寻找的是给出任何Timezone缩写,例如PSTPST,忽略当前的日期时间(例如现在),返回所有可能的时区名称,在本例中是包含的列表。

谢谢

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2017-08-06 05:41:01

我喜欢unutbu的回答,它让我找到了对我有用的答案。我有用户的区域设置,所以我发现我可以使用它来消除时区缩写之间的歧义。

换句话说,这解决了以下问题:

代码语言:javascript
运行
复制
In [242]: 'Asia/Shanghai' in tzones['CST']
Out[242]: True

In [243]: 'US/Central' in tzones['CST']
Out[243]: True

这一职能需要有两个字母的国家代码:

代码语言:javascript
运行
复制
def GetTimeZoneName(timezone, country_code):

    #see if it's already a valid time zone name
    if timezone in pytz.all_timezones:
        return timezone

    #if it's a number value, then use the Etc/GMT code
    try:
        offset = int(timezone)
        if offset > 0:
            offset = '+' + str(offset)
        else:
            offset = str(offset)
        return 'Etc/GMT' + offset
    except ValueError:
        pass

    #look up the abbreviation
    country_tzones = None
    try:
        country_tzones = pytz.country_timezones[country_code]
    except:
        pass

    set_zones = set()
    if country_tzones is not None and len(country_tzones) > 0:
        for name in country_tzones:
            tzone = pytz.timezone(name)
            for utcoffset, dstoffset, tzabbrev in getattr(tzone, '_transition_info', [[None, None, datetime.datetime.now(tzone).tzname()]]):
                if tzabbrev.upper() == timezone.upper():
                    set_zones.add(name)

        if len(set_zones) > 0:
            return min(set_zones, key=len)

        # none matched, at least pick one in the right country
        return min(country_tzones, key=len)


    #invalid country, just try to match the timezone abbreviation to any time zone
    for name in pytz.all_timezones:
        tzone = pytz.timezone(name)
        for utcoffset, dstoffset, tzabbrev in getattr(tzone, '_transition_info', [[None, None, datetime.datetime.now(tzone).tzname()]]):
            if tzabbrev.upper() == timezone.upper():
                set_zones.add(name)

    return min(set_zones, key=len)

这将返回CST的正确时区:

代码语言:javascript
运行
复制
>>> GetTimeZoneName('CST','CN')
'Asia/Shanghai'

>>> GetTimeZoneName('CST','US')
'America/Detroit'
票数 5
EN

Stack Overflow用户

发布于 2016-03-17 17:46:25

由于您希望忽略当前的日期时间,因此您似乎希望在过去的中的任何时间找到在上使用给定缩写的任何时区。该信息在Olson数据库中,并可通过pytz访问。但是,pytz将此信息存储在私有属性tzone._transition_info中。

代码语言:javascript
运行
复制
import collections
import datetime as DT
import pytz

tzones = collections.defaultdict(set)
abbrevs = collections.defaultdict(set)

for name in pytz.all_timezones:
    tzone = pytz.timezone(name)
    for utcoffset, dstoffset, tzabbrev in getattr(
            tzone, '_transition_info', [[None, None, DT.datetime.now(tzone).tzname()]]):
        tzones[tzabbrev].add(name)
        abbrevs[name].add(tzabbrev)

gettattr的第三个(默认)参数的原因是处理几个时区,如Africa/Bujumbura,这些时区从来没有任何转换。因此,在这些情况下的缩写是当前的缩写。

代码语言:javascript
运行
复制
In [94]: tzones['PST']
Out[94]: 
{'America/Bahia_Banderas',
 'America/Boise',
 'America/Creston',
 'America/Dawson',
 'America/Dawson_Creek',
 'America/Ensenada',
 'America/Hermosillo',
 'America/Inuvik',
 'America/Juneau',
 'America/Los_Angeles',
 'America/Mazatlan',
 'America/Metlakatla',
 'America/Santa_Isabel',
 'America/Sitka',
 'America/Tijuana',
 'America/Vancouver',
 'America/Whitehorse',
 'Canada/Pacific',
 'Canada/Yukon',
 'Mexico/BajaNorte',
 'Mexico/BajaSur',
 'PST8PDT',
 'Pacific/Pitcairn',
 'US/Pacific',
 'US/Pacific-New'}
代码语言:javascript
运行
复制
In [95]: tzones['PDT']
Out[95]: 
{'America/Boise',
 'America/Dawson',
 'America/Dawson_Creek',
 'America/Ensenada',
 'America/Juneau',
 'America/Los_Angeles',
 'America/Metlakatla',
 'America/Santa_Isabel',
 'America/Sitka',
 'America/Tijuana',
 'America/Vancouver',
 'America/Whitehorse',
 'Canada/Pacific',
 'Canada/Yukon',
 'Mexico/BajaNorte',
 'PST8PDT',
 'US/Pacific',
 'US/Pacific-New'}
代码语言:javascript
运行
复制
In [97]: abbrevs['America/Los_Angeles']
Out[97]: {'LMT', 'PDT', 'PPT', 'PST', 'PWT'}

正如保罗指出所指出的,时区缩写是模棱两可的--它们不一定映射到具有相同utcoffset集的时区。例如,Asia/ShanghaiUS/Central都使用CST时区缩写。

代码语言:javascript
运行
复制
In [242]: 'Asia/Shanghai' in tzones['CST']
Out[242]: True

In [243]: 'US/Central' in tzones['CST']
Out[243]: True
票数 7
EN

Stack Overflow用户

发布于 2020-10-10 03:58:44

更新py3.9+ (如PEP615中所讨论的),新的区域信息模块可能会有所帮助:

代码语言:javascript
运行
复制
from collections import defaultdict
from datetime import datetime as dt
from zoneinfo import available_timezones, ZoneInfo

now = dt.utcnow()
tz_key = lambda tz: ZoneInfo(tz).tzname(now)
tz_map = defaultdict(list)

for tz in available_timezones():
    tz_map[tz_key(tz)].append(tz)
tz_map = {k: sorted(v) for k, v in tz_map.items()}

例如,print(tz_map['PDT'])会产生:['America/Ensenada', 'America/Los_Angeles', 'America/Santa_Isabel', 'America/Tijuana', 'America/Vancouver', 'Canada/Pacific', 'Mexico/BajaNorte', 'PST8PDT', 'US/Pacific', 'US/Pacific-New']

注:时区从本地安装的时区数据中提取.您还可以添加第一方tzdata库(不是在标准库中,而是由python的核心开发人员维护:使用pip install tzdata)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36067621

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档