使用Python dateutil,如何判断时区字符串是否"valid"?



我使用以下代码进行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)

解决方案#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!')

Sergey的回答很好,但是如果你选择解决方案#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 3.9开始,zoneinfo是一个内置模块,您可以在不需要外部模块的情况下测试它,如pytz:

from zoneinfo import available_timezones
valid_timezone = "America/Los_Angeles"
invalid_timezone = "spam"
def timezone_is_valid(timezone_string):
  return timezone_string in available_timezones()
timezone_is_valid(valid_timezone)  # Returns True
timezone_is_valid(invalid_timezone)  # Returns False

相关内容

  • 没有找到相关文章

最新更新