如何获取日期时间使用的时区规则版本



在John Skeet关于在存储未来日期时间时处理时区信息的博客文章中,他建议将时区规则的版本与本地时间和时区id一起存储在数据库中。

他的例子:

ID: 1
Name: KindConf
LocalStart: 2022-07-10T09:00:00
Address: Europaplein 24, 1078 GZ Amsterdam, Netherlands
TimeZoneId: Europe/Amsterdam
UtcStart: 2022-07-10T07:00:00Z
TimeZoneRules: 2019a

在python中,如何获得datetime使用的时区规则版本例如:

date.astimezone(zoneinfo.ZoneInfo('US/Pacific'))

获取时区规则的方法取决于用于创建tzinfo实例的库。

如果使用pytz,则使用的时区数据库为Olson时区数据库。

import pytz
print(pytz.OLSEN_VERSION)  # e.g. 2021a

使用zoneinfo时,默认情况下使用系统的时区数据。

从文档:默认情况下,zoneinfo使用系统的时区数据(如果可用(;如果没有可用的系统时区数据,则库将返回使用PyPI上可用的第一方tzdata包

有两种选择:

  1. 查找特定于平台的获取版本号的方法
  2. 使用tzdata库设置zoneinfo,使时区版本号随时可用

对于选项2:

要设置zoneinfo以忽略系统数据并使用tzdata包,请设置环境变量PYTHONTZPATH="">

IANA版本号由tzdata:导出

import tzdata
print(tzdata.IANA_VERSION). # e.g. 2021e

这是一个仅限POSIX的解决方案,适用于tzdata v.2018a+:

import os
from pathlib import Path  
import re
import zoneinfo 

def get_system_tzdata_version():
"""
Get the used tzdata version
NOTE: Only supports tzdata versions 2018a and
later, as the version info was added to tzdata.zi
in tzdata version 2018a.
Returns
-------
version: str | None
The version of the system tzdata.
If version could not be read from tzdata.zi,
return None.
"""
# This is a file that contains a copy of all data
# in the tzdata database. It has been part of the
# tzdata since release 2017c.
tzdata_zi_fname = "tzdata.zi"
if os.name == "nt":  # Windows
raise NotImplementedError("Currently, only POSIX is supported")
# Assuming we are in posix system
for p in zoneinfo.TZPATH:
p = Path(p)
tzdata_zi = p / tzdata_zi_fname
if p.exists() and tzdata_zi.exists():
break
with open(tzdata_zi) as f:
contents = f.read()
match = re.match(r"^s*#s*versions+(?P<version>.*)n", contents)
if not match:
# Could not find version string from the tzdata.zi file
return None
return match.group("version")

解释

  • zoneinfo默认使用系统时区信息,在POSIX系统上,该信息来自tzdata(系统(包
  • zoneinfo读取tzdata数据的位置列在zoneinfo中。TZPATH
  • 自tzdata版本2018a以来,tzdata数据库的版本信息已写入名为tzdata.zi的文件。[tzdata新闻]

最新更新