Airflow Summit 2025 將於 10 月 07-09 日舉行。立即註冊獲取早鳥票!

時區

時區支援預設啟用。Airflow 在內部和資料庫中將日期時間資訊儲存為 UTC。它允許您使用依賴於時區的排程來執行您的 DAG。目前,Airflow 不會在使用者介面中將其轉換為終端使用者的時區。它在那裡總是以 UTC 顯示。同樣,運算子中使用的模板也不會轉換。時區資訊是公開的,由 DAG 的編寫者決定如何處理它。

如果您的使用者居住在多個時區,並且您希望根據每個使用者的本地時間顯示日期時間資訊,這會非常方便。

即使您僅在一個時區執行 Airflow,將資料以 UTC 格式儲存在資料庫中仍然是最佳實踐(在 Airflow 支援時區感知之前,這也一直是推薦甚至強制的設定)。主要原因是許多國家/地區使用夏令時 (DST),在春季將時鐘向前撥,在秋季向後撥。如果您在本地時間工作,很可能會在轉換髮生時每年遇到兩次錯誤。(pendulum 和 pytz 文件更詳細地討論了這些問題。)對於簡單的 DAG 來說,這可能無關緊要,但如果您從事金融服務等行業,需要滿足每日截止日期,這將是一個問題。

時區在 airflow.cfg 中設定。預設情況下設定為 UTC,但您可以更改它以使用系統的設定或任意 IANA 時區,例如 Europe/Amsterdam。它依賴於 pendulum,後者比 pytz 更準確。安裝 Airflow 時會安裝 Pendulum。

注意

Pendulum 預設依賴於其自己的時區資料庫,該資料庫的更新頻率不如 IANA 資料庫。您可以透過將 PYTZDATA_TZDATADIR 環境變數設定為系統的資料庫路徑(例如 /usr/share/zoneinfo)來使 Pendulum 依賴於系統的資料庫。

Web UI

預設情況下,Web UI 將以 UTC 顯示時間。可以透過使用右上角的選單(點選時鐘啟用)來更改顯示的時區。

../_images/ui-timezone-chooser.png

“本地”時區由瀏覽器時區檢測。“伺服器”值來自 [core] 部分中的 default_timezone 設定。

使用者選擇的時區儲存在 LocalStorage 中,因此是按瀏覽器設定的。

注意

UI 預設使用系統時區。使用者可以透過 UI 的時區選擇器更改其時區偏好設定。

概念

樸素(naive)和感知(aware)的 datetime 物件

Python 的 datetime.datetime 物件有一個 tzinfo 屬性,可用於儲存時區資訊,表示為 datetime.tzinfo 子類的例項。設定此屬性並描述偏移量時,datetime 物件是感知的(aware)。否則,它是樸素的(naive)。

您可以使用 timezone.is_localized()timezone.is_naive() 來確定 datetime 物件是感知(aware)還是樸素(naive)。

因為 Airflow 使用時區感知的 datetime 物件。如果您的程式碼建立 datetime 物件,它們也需要是感知的(aware)。

from airflow.utils import timezone

now = timezone.utcnow()
a_date = timezone.datetime(2017, 1, 1)

樸素 datetime 物件的解釋

雖然 Airflow 完全以時區感知的方式執行,但為了保持向後相容性,它仍然接受 DAG 定義中 start_datesend_dates 的樸素日期時間物件。如果遇到樸素的 start_dateend_date,將應用預設時區。應用方式是假設樸素日期時間已處於預設時區。換句話說,如果您的預設時區設定為 Europe/Amsterdam 並建立了樸素的 datetime start_date 物件 datetime(2017, 1, 1),則假定這是 2017 年 1 月 1 日阿姆斯特丹時間的 start_date

dag = DAG(
    "my_dag",
    start_date=pendulum.datetime(2017, 1, 1, tz="UTC"),
    default_args={"retries": 3},
)
op = BashOperator(task_id="hello_world", bash_command="Hello World!", dag=dag)
print(op.retries)  # 3

不幸的是,在夏令時轉換期間,某些日期時間可能不存在或存在歧義。在這種情況下,pendulum 會引發異常。因此,啟用時區支援後,您應始終建立感知的 datetime 物件。

實際上,這很少成為問題。Airflow 在模型和 DAG 中提供時區感知的 datetime 物件,而且通常情況下,新的 datetime 物件是透過 timedelta 算術從現有物件建立的。應用程式碼中唯一經常建立的 datetime 物件是當前時間,而 timezone.utcnow() 會自動正確處理。

預設時區

預設時區是由 [core] 部分下的 default_timezone 設定定義的時區。如果您剛安裝 Airflow,它將設定為 utc,這是推薦的設定。您也可以將其設定為 system 或 IANA 時區(例如 Europe/Amsterdam)。DAG 也在 Airflow worker 上評估,因此確保所有 Airflow 節點上的此設定一致非常重要。

[core]
default_timezone = utc

注意

有關設定配置的更多資訊,請參閱設定配置選項

時區感知的 DAG

建立時區感知的 DAG 非常簡單。只需確保使用 pendulum 提供時區感知的 start_date。不要嘗試使用標準庫的 timezone 物件,因為它們已知存在限制,我們特意不允許在 DAG 中使用它們。

import pendulum

dag = DAG("my_tz_dag", start_date=pendulum.datetime(2016, 1, 1, tz="Europe/Amsterdam"))
op = EmptyOperator(task_id="empty", dag=dag)
print(dag.timezone)  # <Timezone [Europe/Amsterdam]>

請注意,雖然可以為任務設定 start_dateend_date,但始終會使用 DAG 時區或全域性時區(按此順序)來計算資料間隔。首次遇到時,開始日期或結束日期將使用與 start_dateend_date 相關聯的時區轉換為 UTC,然後在此基礎上進行計算,時區資訊將被忽略。

注意

編寫時區感知的 DAG 時,必須確保底層時區庫(例如:pendulum)已更新,包含了最新的法規變更(夏令時變更等)。預計時間發生變化時,您應與底層時區庫確認轉換是否會按預期發生。可能需要更新庫版本。一般建議是,如果可能,最好以 UTC 編寫 DAG。

模板

Airflow 在模板中返回時區感知的 datetime 物件,但不會將它們轉換為本地時間,因此它們仍保持 UTC。這由 DAG 自行處理。

import pendulum

local_tz = pendulum.timezone("Europe/Amsterdam")
local_tz.convert(logical_date)

Cron 排程

使用 Cron 排程的時區感知的 DAG 會遵守夏令時。例如,一個開始日期為 US/Eastern 時區且排程為 0 0 * * * 的 DAG 在夏令時期間將每天在 UTC 04:00 執行,否則在 05:00 執行。

時間差

使用 timedeltarelativedelta 排程的時區感知的 DAG 會遵守開始日期的夏令時,但在排程後續執行時不會調整夏令時。例如,一個開始日期為 pendulum.datetime(2020, 1, 1, tz="UTC") 且排程間隔為 timedelta(days=1) 的 DAG 將每天在 UTC 05:00 執行,無論是否夏令時。

此條目是否有幫助?