zoneinfo — IANA 時區支援

3.9 版本新增。

原始碼: Lib/zoneinfo


zoneinfo 模組提供了一個具體的時區實現,用於支援 IANA 時區資料庫,該資料庫最初在 PEP 615 中指定。預設情況下,zoneinfo 使用系統的時區資料(如果可用);如果系統時區資料不可用,則該庫將回退到使用 PyPI 上提供的第一方 tzdata 包。

另請參閱

模組: datetime

提供 timedatetime 型別,ZoneInfo 類被設計為與它們一起使用。

軟體包 tzdata

由 CPython 核心開發人員維護的第一方軟體包,透過 PyPI 提供時區資料。

可用性: 不適用於 WASI。

此模組在 WebAssembly 上無法工作或不可用。有關更多資訊,請參閱 WebAssembly 平臺

使用 ZoneInfo

ZoneInfodatetime.tzinfo 抽象基類的具體實現,旨在附加到 tzinfo,可以透過建構函式、datetime.replace 方法或 datetime.astimezone

>>> 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 包中查詢匹配項。此行為可以透過三種方式配置:

  1. 預設的 TZPATH(如果未以其他方式指定)可以在 編譯時 進行配置。

  2. 可以使用 環境變數 配置 TZPATH

  3. 執行時,可以使用 reset_tzpath() 函式操作搜尋路徑。

編譯時配置

預設的 TZPATH 包括時區資料庫的幾個常見部署位置(在 Windows 上除外,因為 Windows 沒有時區資料的“眾所周知”的位置)。在 POSIX 系統上,下游分發者和從原始碼構建 Python 的人員如果知道其系統時區資料的部署位置,可以透過指定編譯時選項 TZPATH(或更有可能使用 configure 標誌 --with-tzpath)來更改預設時區路徑,該選項應是以 os.pathsep 分隔的字串。

在所有平臺上,配置的值都可用作 sysconfig.get_config_var() 中的 TZPATH 鍵。

環境配置

當初始化 TZPATH 時(在匯入時或在呼叫 reset_tzpath() 時不帶引數),zoneinfo 模組將使用環境變數 PYTHONTZPATH(如果存在)來設定搜尋路徑。

PYTHONTZPATH

這是一個以 os.pathsep 分隔的字串,其中包含要使用的時區搜尋路徑。它必須僅由絕對路徑而不是相對路徑組成。PYTHONTZPATH 中指定的相對元件將不會被使用,但否則指定相對路徑時的行為是實現定義的;CPython 將引發 InvalidTZPathWarning,但其他實現可以自由地忽略錯誤的元件或引發異常。

要將系統設定為忽略系統資料並改用 tzdata 包,請設定 PYTHONTZPATH=""

執行時配置

TZ 搜尋路徑也可以在執行時使用 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__()

透過此建構函式建立的物件無法被 pickle 序列化(請參閱 pickle 序列化)。

classmethod ZoneInfo.no_cache(key)

一個繞過建構函式快取的備用建構函式。它與主建構函式相同,但在每次呼叫時返回一個新物件。這最有可能用於測試或演示目的,但也可用於建立具有不同快取失效策略的系統。

透過此建構函式建立的物件在反序列化時也將繞過反序列化程序的快取。

注意

使用此建構函式可能會以令人驚訝的方式更改日期時間的語義,僅在您知道需要使用時才使用它。

以下類方法也可用

classmethod ZoneInfo.clear_cache(*, only_keys=None)

一種使 ZoneInfo 類上的快取失效的方法。如果未傳遞任何引數,則所有快取都將失效,並且對每個鍵的主建構函式的下一次呼叫將返回一個新例項。

如果將鍵名稱的可迭代物件傳遞給 only_keys 引數,則只會從快取中刪除指定的鍵。傳遞給 only_keys 但未在快取中找到的鍵將被忽略。

警告

呼叫此函式可能會以令人驚訝的方式更改使用 ZoneInfo 的日期時間的語義;這會修改模組狀態,因此可能會產生廣泛的影響。僅在您知道需要使用時才使用它。

該類具有一個屬性

ZoneInfo.key

這是一個只讀的 屬性,返回傳遞給建構函式的 key 的值,該值應該是 IANA 時區資料庫中的查詢鍵(例如,America/New_YorkEurope/ParisAsia/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()ZoneInforepr 是實現定義的,並且在版本之間不一定穩定,但保證它不是有效的 ZoneInfo 鍵。

Pickle 序列化

ZoneInfo 物件不是序列化所有轉換資料,而是按鍵序列化,並且從檔案構造的 ZoneInfo 物件(即使指定了 key 的值)也無法 pickle 序列化。

ZoneInfo 檔案的行為取決於其構造方式

  1. ZoneInfo(key):使用主建構函式構造時,ZoneInfo 物件按鍵序列化,並且在反序列化時,反序列化程序使用主建構函式,因此可以預期這些物件與對同一時區的其他引用相同。例如,如果 europe_berlin_pkl 是一個字串,其中包含從 ZoneInfo("Europe/Berlin") 構造的 pickle,則可以預期以下行為

    >>> a = ZoneInfo("Europe/Berlin")
    >>> b = pickle.loads(europe_berlin_pkl)
    >>> a is b
    True
    
  2. 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
    
  3. ZoneInfo.from_file(fobj, /, key=None):從檔案構造時,ZoneInfo 物件在進行 pickle 時引發異常。如果終端使用者想要 pickle 從檔案構造的 ZoneInfo,建議他們使用包裝器型別或自定義序列化函式:按鍵序列化或儲存檔案物件的內容並序列化該內容。

這種序列化方法要求所需的鍵的時區資料在序列化和反序列化端都可用,類似於類和函式的引用在序列化和反序列化環境中都存在的方式。這也意味著,當在具有不同版本時區資料的環境中反序列化 pickle 的 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.ZoneInfoNotFoundError

當由於在系統上找不到指定的鍵而導致 ZoneInfo 物件的構造失敗時引發。這是 KeyError 的子類。

exception zoneinfo.InvalidTZPathWarning

PYTHONTZPATH 包含將被過濾掉的無效元件(例如相對路徑)時引發。