zoneinfo — IANA 時區支援

在 3.9 版本中新增。

原始碼: Lib/zoneinfo


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

參見

模組: datetime

提供了 timedatetime 型別,ZoneInfo 類旨在與它們一起使用。

tzdata

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

可用性:非 WASI。

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

使用 ZoneInfo

ZoneInfodatetime.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

當從另一個時區轉換時,摺疊將設定為正確的值。

>>> 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 flag --with-tzpath),這是一個由 os.pathsep 分隔的字串,來更改預設時區路徑。

在所有平臺上,配置的值都可以在 sysconfig.get_config_var() 中以 TZPATH 鍵的形式獲得。

環境變數配置

在初始化 TZPATH 時(無論是在匯入時還是在呼叫 reset_tzpath() 且不帶引數時),如果存在環境變數 PYTHONTZPATHzoneinfo 模組將使用它來設定搜尋路徑。

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(file_obj, /, key=None)

從返回位元組的類檔案物件(例如以二進位制模式開啟的檔案或 io.BytesIO 物件)構造一個 ZoneInfo 物件。與主建構函式不同,這總是構造一個新物件。

key 引數設定區域的名稱,用於 __str__()__repr__()

透過此建構函式建立的物件不能被 pickle 序列化(參見 pickling)。

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 Common Locale Data Repository)之類的專案可用於從這些鍵獲取更使用者友好的字串。

字串表示

當對 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(file_obj, /, key=None): 當從檔案構造時,ZoneInfo 物件在 pickle 序列化時會引發異常。如果終端使用者想要 pickle 序列化從檔案構造的 ZoneInfo,建議他們使用包裝型別或自定義序列化函式:要麼按鍵序列化,要麼儲存檔案物件的內容並序列化它。

這種序列化方法要求所需鍵的時區資料在序列化和反序列化端都可用,這類似於對類和函式的引用預計在序列化和反序列化環境中都存在的方式。這也意味著當在不同版本的時區資料的環境中反序列化 pickled ZoneInfo 時,不保證結果的一致性。

函式

zoneinfo.available_timezones()

獲取一個集合,其中包含時區路徑上所有可用的 IANA 時區的有效鍵。每次呼叫該函式時都會重新計算。

此函式僅包含規範區域名稱,不包括“特殊”區域,例如 posix/right/ 目錄下的區域,或 posixrules 區域。

注意

此函式可能會開啟大量檔案,因為確定時區路徑上的檔案是否為有效時區的最佳方法是讀取開頭的“魔術字串”。

備註

這些值不打算暴露給終端使用者;對於面向使用者的元素,應用程式應使用 CLDR(Unicode Common Locale Data Repository)等工具來獲取更使用者友好的字串。另請參閱 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 包含將被過濾掉的無效元件(例如相對路徑)時引發。