说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
zoneinfo 模块根据 PEP 615 的最初说明提供了具体的时区实现来支持 IANA 时区数据库。 按照默认设置,zoneinfo 会在可能的情况下使用系统的时区数据;如果系统时区数据不可用,该库将回退为使用 PyPI 上提供的 tzdata 第一方包。
互联网号码分配局(英语:Internet Assigned Numbers Authority,缩写IANA),是一家互联网地址指派机构,管理国际互联网中使用的IP地址、域名和许多其它参数的机构。IP地址、自治系统成员以及许多顶级和二级域名分配的日常职责由国际互联网注册中心(IR)和地区注册中心承担。IANA是由ICANN管理的。
时区信息数据库,又称 TZ database、Zoneinfo database,是一个主要应用于电脑程序以及操作系统的、可协作编辑世界时区信息的数据库。由于该数据库由David Olson创立,因而有些地方也将其称作Olson数据库。数据库由Paul Eggert进行编辑和维护。
它的显著特色是由上面提到的Paul Eggert设计的一套通用时区命名规则,例如"America/New_York"和"Europe/Paris"。数据库试图记录自1970年(Unix元年)以来时区和城市的变化,并且还包含一些时间的转换,例如夏令时和闰秒。
在时区信息数据库中,“时区”被定义为自1970年当地时间统一的国家及地区。这种定义方法关注于一个具有相同时间的地理区域,它与其他对时区的定义方法不同的是,其他方法关注于不同时区与本初子午线之间的时差。因而数据库中定义的每个时区都会记录一系列对协调世界时的时差,同一时区内一般会包含标准时间和夏令时两种。
IANA 时区支持面临的最大挑战之一是保持数据的最新;从1997年到2020年,每年有 3 到 21 次发布,通常是为了响应时区规则的变化,但这几乎没有通知。为了保持最新,并让系统管理员控制数据源,我们建议尽可能使用系统部署的时区数据。然而,并非所有系统都提供可公开访问的时区数据库——尤其是Windows使用不同的系统来管理时区——因此,如果可用,zoneinfo 会退回到 PyPI 上提供的可安装第一方软件包tzdata。如果未找到系统zoneinfo文件,但安装了tzdata,则主zoneinfo构造函数将使用tzdata作为时区源。
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"))
dt
# 2020-10-31 12:00:00-07:00
dt.tzname()
# 'PDT'
# 注:'PDT' 太平洋夏令时,'PST' 太平洋标准时间
以此方式构造的日期时间对象可兼容日期时间运算并可在无需进一步干预的情况下处理夏令时转换:
dt_add = dt + timedelta(days=1)
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"))
dt
# 2020-11-01 01:00:00-07:00
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
dt_utc.astimezone(LOS_ANGELES)
# 2020-11-01 01:00:00-07:00
# After the PDT -> PST transition
(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 模块不直接提供时区数据,而是从系统时区数据库或第一方 PyPI 包 tzdata(如果可用)中提取时区信息。一些系统(尤其是 Windows 系统)没有可用的 IANA 数据库,因此对于需要时区数据的跨平台兼容性项目,建议声明对数据的依赖性。如果系统数据和 tzdata 都不可用,则对 ZoneInfo 的所有调用都将引发 ZoneInfo NotFoundError。
一个具体的 datetime.tzinfo 子类,它代表一个由字符串 key 所指定的 IANA 时区。 对主构造器的调用将总是返回可进行标识比较的对象;但是另一种方式,对所有的 key 值通过 ZoneInfo.clear_cache() 禁止缓存失效,对以下断言将总是为真值:
a = ZoneInfo(key)
b = ZoneInfo(key)
assert a is b
key 必须采用相对的标准化 POSIX 路径的形式,其中没有对上一层级的引用。 如果传入了不合要求的键则构造器将引发 ValueError。
如果没有找到匹配 key 的文件,构造器将引发 ZoneInfoNotFoundError。
ZoneInfo 类具有两个替代构造器:
基于一个返回字节串的文件类对象(例如一个以二进制模式打开的文件或是一个 io.BytesIO 对象)构造 ZoneInfo 对象。 不同于主构造器,此构造器总是会构造一个新对象。
key 形参设置时区名称以供 __str__()
和 __repr__()
使用。
由此构造器创建的对象不可被封存 (参见 pickling)。
一个绕过构造器缓存的替代构造器。 它与主构造器很相似,但每次调用都会返回一个新对象。 此构造器在进行测试或演示时最为适用,但它也可以被用来创建具有不同缓存失效策略的系统。
由此构造器创建的对象在被解封时也会绕过反序列化进程的缓存。
警告 使用此构造器可以会以令人惊讶的方式改变日期时间对象的语义,只有在你确定你的需求时才使用它。
也可以使用以下的类方法:
一个可在 ZoneInfo 类上禁用缓存的方法。 如果不传入参数,则会禁用所有缓存并且下次对每个键调用主构造器将返回一个新实例。
如果将一个键名称的可迭代对象传给 only_keys 形参,则将只有指定的键会被从缓存中移除。 传给 only_keys 但在缓存中找不到的键会被忽略。
警告 发起调用此函数可能会以令人惊讶的方式改变使用 ZoneInfo 的日期时间对象的语义;这会修改进程范围内的全局状态并因此可能产生大范围的影响。 只有在你确定你的需求时才使用它。
该类具有一个属性:
这是一个只读的 attribute,它返回传给构造器的 key 的值,该值应为一个 IANA 时区数据库的查找键 (例如 America/New_York, Europe/Paris 或 Asia/Tokyo)。
对于不指定 key 形参而是基于文件构造时区,该属性将设为 None。
注解: 尽管将这些信息暴露给最终用户是一种比较普通的做法,但是这些值被设计作为代表相关时区的主键而不一定是面向用户的元素。 CLDR (Unicode 通用区域数据存储库) 之类的项目可被用来根据这些键获取更为用户友好的字符串。
当在 ZoneInfo 对象上调用 str 时返回的字符串表示默认会使用 ZoneInfo.key 属性(参见该属性文档中的用法注释):
from zoneinfo import ZoneInfo
# 北京时间
zone = ZoneInfo("Asia/Shanghai")
str(zone)
# 'Asia/Shanghai'
dt = datetime(2022, 2, 1, 3, 15, tzinfo=zone)
f"{dt.isoformat()} [{dt.tzinfo}]"
# '2022-02-01T03:15:00+08:00 [Asia/Shanghai]'
对于基于文件而非指定 key 形参所构建的对象,str 会回退为调用 repr()。 ZoneInfo 的 repr 是由具体实现定义的并且不一定会在不同版本间保持稳定,但它保证不会是一个有效的 ZoneInfo 键。
ZoneInfo 对象的序列化是基于键的,而不是序列化所有过渡数据,并且基于文件构造的 ZoneInfo 对象(即使是指定了 key 值的对象)不能被封存。
ZoneInfo 文件的行为取决于它的构造方式:
当使用主构造器构造时,会基于键序列化一个 ZoneInfo 对象,而当反序列化时,反序列化过程会使用主构造器,因此预期它们与其他对同一时区的引用会是同一对象。 例如,如果 europe_berlin_pkl 是一个包含基于 ZoneInfo("Europe/Berlin") 构建的封存数据的字符串,你可以预期出现以下的行为:
>>> a = ZoneInfo("Europe/Berlin")
>>> b = pickle.loads(europe_berlin_pkl)
>>> a is b
True
当通过绕过缓存的构造器构造时,ZoneInfo 对象也会基于键序列化,但当反序列化时,反序列化过程会使用绕过缓存的构造器。 如果 europe_berlin_pkl_nc 是一个包含基于 ZoneInfo.no_cache("Europe/Berlin") 构造的封存数据的字符串,你可以预期出现以下的行为:
>>> a = ZoneInfo("Europe/Berlin")
>>> b = pickle.loads(europe_berlin_pkl_nc)
>>> a is b
False
当通过文件构造时,ZoneInfo 对象会在封存时引发异常。 如果最终用户想要封存通过文件构造的 ZoneInfo,则推荐他们使用包装类型或自定义序列化函数:或者基于键序列化,或者存储文件对象的内容并将其序列化。
以上序列化方法要求所需键的时区数据在序列化和反序列化中均可用,类似于在序列化和反序列化环境中都预期存在对类和函数的引用的方式。 这还意味着在具有不同时区数据版本的环境中当解封被封存的 ZoneInfo 时并不会保证结果的一致性。
获取一个包含可用 IANA 时区的在时区路径的任何位置均可用的全部有效键的集合。 每次调用该函数时都会重新计算。
此函数仅包括规范时区名称而不包括“特殊”时区如位于 posix/ 和 right/ 目录下的时区或 posixrules 时区。
警告 此函数可能会打开大量的文件,因为确定时区路径上某个文件是否为有效时区的最佳方式是读取开头位置的“魔术字符串”。
注解 这些值并不被设计用来对外公开给最终用户;对于面向用户的元素,应用程序应当使用 CLDR (Unicode 通用区域数据存储库) 之类来获取更为用户友好的字符串。 另请参阅 ZoneInfo.key 中的提示性说明。
设置或重置模块的时区搜索路径 (TZPATH)。 当不带参数调用时,TZPATH 会被设为默认值。
调用 reset_tzpath 将不会使 ZoneInfo 缓存失效,因而在缓存未命中的情况下对主 ZoneInfo 构造器的调用将只使用新的 TZPATH。
to 形参必须是由字符串或 os.PathLike 组成的 sequence 或而不是字符串,它们必须都是绝对路径。 如果所传入的不是绝对路径则将引发 ValueError。
zoneinfo.TZPATH 表示时区搜索路径的只读序列 -- 当通过键构造 ZoneInfo 时,键会与 TZPATH 中的每个条目进行合并,并使用所找到的第一个文件。
TZPATH 可以只包含绝对路径,绝不包含相对路径,无论它是如何配置的。
zoneinfo.TZPATH 所指向的对象可能随着对 reset_tzpath() 的调用而改变,因此推荐使用 zoneinfo.TZPATH 而不是从 zoneinfo 导入 TZPATH 或是将 zoneinfo.TZPATH 赋值给一个长期变量。
exception zoneinfo.ZoneInfoNotFoundError:当一个 ZoneInfo 对象的构造由于在系统中找不到指定的键而失败时引发。 这是 KeyError 的一个子类。
exception zoneinfo.InvalidTZPathWarning:当 PYTHONTZPATH 包含将被过滤掉的无效组件,例如一个相对路径时引发。
更新时间:2022-01-30 12:40:32 标签:python 时间 时区