zoneinfo --- IANA 時區支援

在 3.9 版被加入.

原始碼:Lib/zoneinfo


zoneinfo 模組提供了一個具體的時區實作,以支援PEP 615 中最初指定的 IANA 時區資料庫。預設情況下,如果可用,zoneinfo 會使用系統的時區資料;如果沒有可用的系統時區資料,該函式庫將轉而使用 PyPI 上可用的第一方tzdata 套件。

也參考

datetime 模組

提供了timedatetime 型別,這些型別是設計來與ZoneInfo 類別一起使用的。

tzdata 套件

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

可用性: not WASI.

此模組在 WebAssembly 平台上不起作用或無法使用。更多資訊請參閱WebAssembly 平台

使用ZoneInfo

ZoneInfodatetime.tzinfo 抽象基底類別的一個具體實作,旨在透過建構函式、datetime.replace 方法或datetime.astimezone 方法附加到tzinfo

>>>fromzoneinfoimportZoneInfo>>>fromdatetimeimportdatetime,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'

以此方式建構的 Datetime 物件與 datetime 運算相容,並能處理日光節約時間轉換而無需進一步干預:

>>>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 將被設定為正確的值:

>>>fromdatetimeimporttimezone>>>LOS_ANGELES=ZoneInfo("America/Los_Angeles")>>>dt_utc=datetime(2020,11,1,8,tzinfo=timezone.utc)>>># 在 PDT 轉換為 PST 之前>>>print(dt_utc.astimezone(LOS_ANGELES))2020-11-01 01:00:00-07:00>>># 在 PDT 轉換為 PST 之後>>>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. runtime,可以使用reset_tzpath() 函式來操作搜尋路徑。

編譯時期設定

預設的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=""

Runtime 設定

TZ 搜尋路徑也可以在 Runtime 使用reset_tzpath() 函式進行設定。這通常不是一個建議的操作,儘管在需要使用特定時區路徑(或需要停用對系統時區的存取)的測試函式中使用它是合理的。

ZoneInfo 類別

classzoneinfo.ZoneInfo(key)

一個具體的datetime.tzinfo 子類別,代表由字串key 指定的 IANA 時區。對主要建構函式的呼叫將總是回傳比較結果相同的物件;換句話說,除非透過ZoneInfo.clear_cache() 使快取失效,否則對於所有key 的值,以下斷言將永遠為真:

a=ZoneInfo(key)b=ZoneInfo(key)assertaisb

key 必須是相對、正規化的 POSIX 路徑形式,且不含上層參照。如果傳入不符合規範的鍵,建構函式將引發ValueError 例外。

如果找不到符合key 的檔案,建構函式將引發ZoneInfoNotFoundError 例外。

ZoneInfo 類別有兩個備用建構函式:

classmethodZoneInfo.from_file(file_obj,/,key=None)

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

key 參數設定了時區的名稱,用於__str__()__repr__()

透過此建構函式建立的物件無法被封裝(參閱pickling)。

classmethodZoneInfo.no_cache(key)

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

透過此建構函式建立的物件,在拆封時也會繞過去序列化過程的快取。

警示

使用此建構函式可能會以意想不到的方式改變你的 datetime 物件的語意,只有在你確定需要時才使用它。

以下類別方法也可用:

classmethodZoneInfo.clear_cache(*,only_keys=None)

一個用於使ZoneInfo 類別上的快取失效的方法。如果沒有傳入引數,所有快取都會失效,且下一次對每個鍵的主要建構函式呼叫都將回傳一個新的實例。

如果將一個包含鍵名的可疊代物件傳遞給only_keys 參數,則只有指定的鍵會從快取中移除。傳遞給only_keys 但在快取中找不到的鍵會被忽略。

警告

呼叫此函式可能會以意想不到的方式改變使用ZoneInfo 的 datetime 物件的語意;這會修改模組狀態,因此可能產生廣泛的影響。只有在你確定需要時才使用它。

該類別有一個屬性:

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 值的物件)也無法被封裝。

ZoneInfo 檔案的行為取決於它的建構方式:

  1. ZoneInfo(key): When constructed with the primary constructor, aZoneInfo object is serialized by key, and when deserialized, thedeserializing process uses the primary and thus it is expected that theseare the same object as other references to the same timezone. For example, ifeurope_berlin_pkl is a string containing a pickleconstructed fromZoneInfo("Europe/Berlin"), one would expect thefollowing behavior:

    >>>a=ZoneInfo("Europe/Berlin")>>>b=pickle.loads(europe_berlin_pkl)>>>aisbTrue
  2. ZoneInfo.no_cache(key):當從繞過快取的建構函式建構時,ZoneInfo 物件也會按鍵序列化,但在去序列化時,去序列化過程會使用繞過快取的建構函式。如果europe_berlin_pkl_nc 是一個包含從ZoneInfo.no_cache("Europe/Berlin") 建構並封裝的字串,會預期以下行為:

    >>>a=ZoneInfo("Europe/Berlin")>>>b=pickle.loads(europe_berlin_pkl_nc)>>>aisbFalse
  3. ZoneInfo.from_file(file_obj,/,key=None):當從檔案建構時,ZoneInfo 物件在封裝時會引發例外。如果終端使用者想要封裝一個從檔案建構的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

有關設定時區搜尋路徑的更多資訊,請參閱設定資料來源

例外與警告

exceptionzoneinfo.ZoneInfoNotFoundError

當建構ZoneInfo 物件因在系統上找不到指定的鍵而失敗時引發。這是KeyError 的一個子類別。

exceptionzoneinfo.InvalidTZPathWarning

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