使用 Python dateutil,如何判断时区字符串是不是“有效”?

Posted

技术标签:

【中文标题】使用 Python dateutil,如何判断时区字符串是不是“有效”?【英文标题】:Using Python dateutil, how to judge a timezone string is "valid" or not?使用 Python dateutil,如何判断时区字符串是否“有效”? 【发布时间】:2017-01-29 05:10:51 【问题描述】:

我正在使用以下代码将 UTC 时间转换为本地时间:

def UTC_to_local(timezone_str, datetime_UTC):
    """
    convert UTC datetime to local datetime. Input datetime is naive
    """
    try:
        from_zone = dateutil.tz.gettz('UTC')
        to_zone = dateutil.tz.gettz(timezone_str)

        datetime_UTC = datetime_UTC.replace(tzinfo=from_zone)

        # Convert time zone
        datetime_local = datetime_UTC.astimezone(to_zone)

    except Exception as e:
        raise

    return datetime_local

如果我给出了正确的 timezone_str(例如,'America/Chicago'),它会按预期工作。 但即使我给出了意外的 timezone_str(例如,'America/Chicago1' 或 'Americaerror/Chicago'),仍然没有例外,它只是返回不同的数字!我认为为意外的时区字符串获取异常比仅仅“做出最佳猜测”更合理。

此外,我发现(使用 IPYTHON):

In [171]: tz.gettz("America/Chicago")
Out[171]: tzfile('/usr/share/zoneinfo/America/Chicago')

In [172]: tz.gettz("America/Chicago1")
Out[172]: tzstr('America/Chicago1')

In [173]: tz.gettz("Americaerror/Chicago")
          (None)

【问题讨论】:

你可以使用pytz:pypi.python.org/pypi/pytz 【参考方案1】:

解决方案#1:如果可以使用pytz

import pytz

if timezone_str in pytz.all_timezones:
    ...
else:
    raise ValueError('Invalid timezone string!')

解决方案 #2:

import os
import tarfile
import dateutil.zoneinfo

zi_path = os.path.abspath(os.path.dirname(dateutil.zoneinfo.__file__))
zonesfile = tarfile.TarFile.open(os.path.join(zi_path, 'dateutil-zoneinfo.tar.gz'))
zonenames = zonesfile.getnames()

if timezone_str in zonenames:
    ...
else:
    raise ValueError('Invalid timezone string!')

【讨论】:

【参考方案2】:

Sergey 的回答很棒,但如果您选择 Solution #1,那么最好使用 pytz.all_timezones_set:

if location in pytz.all_timezones_set
    ...

这是两者的速度比较:

In [14]: %timeit "Asia/Omsk" in pytz.all_timezones
3.09 µs ± 7.66 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [15]: %timeit "Asia/Omsk" in pytz.all_timezones_set
96.5 ns ± 0.0991 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

注意:签入pytz.all_timezones 的速度取决于搜索的项目。我选择了列表中间的那一项(Asia/Omsk 是 593 项中的第 296 项)。

【讨论】:

以上是关于使用 Python dateutil,如何判断时区字符串是不是“有效”?的主要内容,如果未能解决你的问题,请参考以下文章

python 时区 dateutil

dateutil.parser.parse() 和丢失的时区信息

HttpClient DateUtils 的时区问题

这是保存时区规则的标准格式吗?

在 Python 中使用时区缩写名称解析日期/时间字符串?

Python:检查解析的日期时间是不是具有正确的时区