zoneinfo
— IANA 时区支持¶
3.9 版新增。
源代码: Lib/zoneinfo
zoneinfo
模块提供了一个具体的时区实现,以支持最初在 PEP 615 中指定的 IANA 时区数据库。默认情况下,如果可用,zoneinfo
使用系统的时区数据;如果没有可用的系统时区数据,该库将回退到使用 PyPI 上可用的第一方 tzdata 包。
另请参阅
可用性:非 Emscripten,非 WASI。
此模块在 WebAssembly 平台 wasm32-emscripten
和 wasm32-wasi
上不可用或不起作用。有关更多信息,请参阅 WebAssembly 平台。
使用 ZoneInfo
¶
ZoneInfo
是 datetime.tzinfo
抽象基类的具体实现,旨在通过构造函数、datetime.replace
方法或 datetime.astimezone
附加到 tzinfo
。
>>> from zoneinfo import ZoneInfo
>>> from datetime import datetime, timedelta
>>> dt = datetime(2020, 10, 31, 12, tzinfo=ZoneInfo("America/Los_Angeles"))
>>> print(dt)
2020-10-31 12:00:00-07:00
>>> dt.tzname()
'PDT'
以这种方式构造的日期时间与日期时间算术兼容,并且无需进一步干预即可处理夏令时转换。
>>> dt_add = dt + timedelta(days=1)
>>> print(dt_add)
2020-11-01 12:00:00-08:00
>>> dt_add.tzname()
'PST'
这些时区还支持 PEP 495 中引入的 fold
属性。在导致时间模糊的偏移转换期间(例如夏令时到标准时间的转换),当 fold=0
时,使用转换*之前*的偏移量,而当 fold=1
时,使用转换*之后*的偏移量,例如:
>>> dt = datetime(2020, 11, 1, 1, tzinfo=ZoneInfo("America/Los_Angeles"))
>>> print(dt)
2020-11-01 01:00:00-07:00
>>> print(dt.replace(fold=1))
2020-11-01 01:00:00-08:00
从另一个时区转换时,fold 将设置为正确的值。
>>> from datetime import timezone
>>> LOS_ANGELES = ZoneInfo("America/Los_Angeles")
>>> dt_utc = datetime(2020, 11, 1, 8, tzinfo=timezone.utc)
>>> # Before the PDT -> PST transition
>>> print(dt_utc.astimezone(LOS_ANGELES))
2020-11-01 01:00:00-07:00
>>> # After the PDT -> PST transition
>>> print((dt_utc + timedelta(hours=1)).astimezone(LOS_ANGELES))
2020-11-01 01:00:00-08:00
数据源¶
zoneinfo
模块不直接提供时区数据,而是从系统时区数据库或第一方 PyPI 包 tzdata(如果可用)中提取时区信息。某些系统(尤其是 Windows 系统)没有可用的 IANA 数据库,因此对于需要时区数据的、以跨平台兼容性为目标的项目,建议声明对 tzdata 的依赖关系。如果系统数据和 tzdata 都不可用,则对 ZoneInfo
的所有调用都将引发 ZoneInfoNotFoundError
。
配置数据源¶
调用 ZoneInfo(key)
时,构造函数首先在 TZPATH
中指定的目录中搜索与 key
匹配的文件,如果失败,则在 tzdata 包中查找匹配项。此行为可以通过三种方式进行配置:
编译时配置¶
默认的 TZPATH
包括时区数据库的几个常见部署位置(Windows 除外,Windows 没有时区数据的“众所周知”位置)。在 POSIX 系统上,下游发行版和那些从源代码构建 Python 并知道其系统时区数据部署位置的人可以通过指定编译时选项 TZPATH
(或者更可能是 configure 标志 --with-tzpath
)来更改默认的时区路径,该选项应该是一个由 os.pathsep
分隔的字符串。
在所有平台上,配置的值都可以作为 sysconfig.get_config_var()
中的 TZPATH
键使用。
环境配置¶
初始化 TZPATH
时(在导入时或在不带参数调用 reset_tzpath()
时),如果存在环境变量 PYTHONTZPATH
,zoneinfo
模块将使用它来设置搜索路径。
- PYTHONTZPATH¶
这是一个以
os.pathsep
分隔的字符串,包含要使用的时区搜索路径。它必须仅包含绝对路径,而不能包含相对路径。在PYTHONTZPATH
中指定的相对组件将不会被使用,但在其他情况下,指定相对路径时的行为是实现定义的;CPython 会引发InvalidTZPathWarning
,但其他实现可以自由地静默忽略错误组件或引发异常。
要将系统设置为忽略系统数据并使用 tzdata 包,请设置 PYTHONTZPATH=""
。
运行时配置¶
也可以在运行时使用 reset_tzpath()
函数配置时区搜索路径。这通常不是一种建议的操作,但在需要使用特定时区路径(或需要禁用对系统时区的访问)的测试函数中使用它是合理的。
ZoneInfo
类¶
- class zoneinfo.ZoneInfo(key)¶
一个具体的
datetime.tzinfo
子类,表示由字符串key
指定的 IANA 时区。对主构造函数的调用将始终返回比较结果相同的对象;换句话说,除非通过ZoneInfo.clear_cache()
使缓存失效,否则对于key
的所有值,以下断言将始终为真a = ZoneInfo(key) b = ZoneInfo(key) assert a is b
key
必须采用相对的、规范化的 POSIX 路径形式,并且没有上级引用。如果传递了不符合规范的键,构造函数将引发ValueError
。如果找不到与
key
匹配的文件,构造函数将引发ZoneInfoNotFoundError
。
ZoneInfo
类有两个备用构造函数
- classmethod ZoneInfo.from_file(fobj, /, key=None)¶
从返回字节的文件类对象(例如,以二进制模式打开的文件或
io.BytesIO
对象)构造一个ZoneInfo
对象。与主构造函数不同,这始终会构造一个新对象。key
参数设置时区的名称,用于__str__()
和__repr__()
。无法序列化通过此构造函数创建的对象(请参阅序列化)。
- classmethod ZoneInfo.no_cache(key)¶
一个绕过构造函数缓存的备用构造函数。它与主构造函数相同,但在每次调用时都会返回一个新对象。这很可能对测试或演示目的有用,但它也可以用于创建一个具有不同缓存失效策略的系统。
通过此构造函数创建的对象在反序列化时也会绕过反序列化进程的缓存。
注意
使用此构造函数可能会以意想不到的方式更改日期时间的语义,只有在您知道需要时才使用它。
以下类方法也可用
- classmethod ZoneInfo.clear_cache(*, only_keys=None)¶
一种使
ZoneInfo
类上的缓存失效的方法。如果没有传递参数,则所有缓存都将失效,并且对每个键的主构造函数的下一次调用将返回一个新实例。如果将键名迭代器传递给
only_keys
参数,则只会从缓存中删除指定的键。传递给only_keys
但在缓存中找不到的键将被忽略。警告
调用此函数可能会以意想不到的方式更改使用
ZoneInfo
的日期时间的语义;这会修改模块状态,因此可能会产生广泛的影响。只有在您知道需要时才使用它。
该类有一个属性
- ZoneInfo.key¶
这是一个只读 属性,返回传递给构造函数的
key
的值,该值应该是 IANA 时区数据库中的查找键(例如America/New_York
、Europe/Paris
或Asia/Tokyo
)。对于从文件构造但未指定
key
参数的时区,这将设置为None
。注意
尽管将这些值公开给最终用户是一种相当普遍的做法,但这些值旨在作为表示相关时区的键,而不一定是面向用户的元素。可以使用 CLDR(Unicode 通用语言环境数据存储库)等项目从这些键中获取更友好的字符串。
字符串表示形式¶
在 ZoneInfo
对象上调用 str
时返回的字符串表示形式默认使用 ZoneInfo.key
属性(请参阅属性文档中的用法说明)
>>> zone = ZoneInfo("Pacific/Kwajalein")
>>> str(zone)
'Pacific/Kwajalein'
>>> dt = datetime(2020, 4, 1, 3, 15, tzinfo=zone)
>>> f"{dt.isoformat()} [{dt.tzinfo}]"
'2020-04-01T03:15:00+12:00 [Pacific/Kwajalein]'
对于从文件中构造的对象,如果没有指定 key
参数,str
会回退到调用 repr()
。 ZoneInfo
的 repr
是由实现定义的,在不同版本之间不一定稳定,但保证不是有效的 ZoneInfo
键。
Pickle 序列化¶
ZoneInfo
对象不是序列化所有转换数据,而是通过键进行序列化,并且从文件构造的 ZoneInfo
对象(即使是指定了 key
值的对象)也不能被 pickle 序列化。
ZoneInfo
文件的行为取决于它的构造方式
ZoneInfo(key)
:当使用主构造函数构造时,ZoneInfo
对象通过键进行序列化,并且在反序列化时,反序列化过程使用主构造函数,因此预期这些对象与对同一时区的其他引用是相同的对象。例如,如果europe_berlin_pkl
是一个包含从ZoneInfo("Europe/Berlin")
构造的 pickle 的字符串,则预期会发生以下行为>>> a = ZoneInfo("Europe/Berlin") >>> b = pickle.loads(europe_berlin_pkl) >>> a is b True
ZoneInfo.no_cache(key)
:当从绕过缓存的构造函数构造时,ZoneInfo
对象也通过键进行序列化,但在反序列化时,反序列化过程使用绕过缓存的构造函数。如果europe_berlin_pkl_nc
是一个包含从ZoneInfo.no_cache("Europe/Berlin")
构造的 pickle 的字符串,则预期会发生以下行为>>> a = ZoneInfo("Europe/Berlin") >>> b = pickle.loads(europe_berlin_pkl_nc) >>> a is b False
ZoneInfo.from_file(fobj, /, key=None)
:当从文件构造时,ZoneInfo
对象在 pickle 序列化时会引发异常。如果最终用户想要 pickle 序列化从文件构造的ZoneInfo
,建议他们使用包装器类型或自定义序列化函数:通过键进行序列化或存储文件对象的内容并对其进行序列化。
这种序列化方法要求在序列化端和反序列化端都可以使用所需键的时区数据,类似于在序列化和反序列化环境中都应该存在对类和函数的引用的方式。这也意味着在使用不同版本的时区数据的环境中对 ZoneInfo
进行反序列化时,不保证结果的一致性。
函数¶
- zoneinfo.available_timezones()¶
获取一个集合,其中包含时区路径上任何位置可用的 IANA 时区的所有有效键。每次调用该函数时都会重新计算。
此函数仅包含规范的时区名称,不包括“特殊”时区,例如
posix/
和right/
目录下的时区,或posixrules
时区。注意
此函数可能会打开大量文件,因为确定时区路径上的文件是否是有效时区的最佳方法是读取开头的“魔术字符串”。
注意
这些值并非设计为向最终用户公开;对于面向用户的元素,应用程序应使用 CLDR(Unicode 通用地区数据存储库)之类的工具来获取对用户更友好的字符串。另请参阅
ZoneInfo.key
上的注意事项。
- zoneinfo.reset_tzpath(to=None)¶
设置或重置模块的时区搜索路径(
TZPATH
)。当不带参数调用时,TZPATH
将设置为默认值。调用
reset_tzpath
不会使ZoneInfo
缓存失效,因此只有在缓存未命中的情况下,对主ZoneInfo
构造函数的调用才会使用新的TZPATH
。to
参数必须是字符串序列或os.PathLike
,而不是字符串,所有这些都必须是绝对路径。如果传递的不是绝对路径,则会引发ValueError
。
全局变量¶
- zoneinfo.TZPATH¶
一个只读序列,表示时区搜索路径 - 当从键构造
ZoneInfo
时,该键将与TZPATH
中的每个条目连接起来,并使用找到的第一个文件。无论如何配置,
TZPATH
都只能包含绝对路径,而不能包含相对路径。zoneinfo.TZPATH
指向的对象可能会因调用reset_tzpath()
而发生变化,因此建议使用zoneinfo.TZPATH
,而不是从zoneinfo
导入TZPATH
或将长期存在的变量分配给zoneinfo.TZPATH
。有关配置时区搜索路径的更多信息,请参阅 配置数据源。
异常和警告¶
- exception zoneinfo.InvalidTZPathWarning¶
当
PYTHONTZPATH
包含将被过滤掉的无效组件(例如相对路径)时引发。