# 時區
默認情況下啟用對時區的支持。 Airflow在內部和數據庫中以UTC格式存儲日期時間信息。 它允許您使用時區相關的計劃運行DAG。 目前,Airflow不會將其轉換為用戶界面中的最終用戶時區。 它始終以UTC顯示。 此外,操作符中使用的模板也不會被轉換。 時區信息是暴露出來的,由DAG的作者負責。
如果您的用戶居住在多個時區,并且您希望根據每個用戶的掛鐘顯示日期時間信息,這將非常方便。
即使您只在一個時區運行Airflow,在數據庫中以UTC格式存儲數據仍然是一種很好的做法(在Airflow成為時區之前也是如此,這也是建議的甚至是必需的設置)。 主要原因是夏令時(DST)。 許多國家都有DST系統,其中時鐘在春季向前移動,在秋季向后移動。 如果您在當地工作,那么當轉換發生時,您可能每年會遇到兩次錯誤。 (鐘擺和pytz文檔更詳細地討論了這些問題。)這對于簡單的DAG可能無關緊要,但如果您處于金融服務中,那么這是一個問題,在這些金融服務中您可以滿足最后期限。
時區在<cite>airflow.cfg中</cite>設置。 默認情況下,它設置為utc,但您將其更改為使用系統設置或任意IANA時區,例如<cite>Europe / Amsterdam</cite> 。 它取決于<cite>鐘擺</cite> ,它比<cite>pytz</cite>更準確。 安裝Airflow時會安裝Pendulum。
請注意,Web UI目前僅以UTC格式運行。
## 概念
### 天真并了解日期時間對象
Python的datetime.datetime對象具有tzinfo屬性,可用于存儲時區信息,表示為datetime.tzinfo的子類的實例。 設置此屬性并描述偏移量時,可以識別日期時間對象。 否則,這是天真的。
您可以使用timezone.is_aware()和timezone.is_naive()來確定日期時間是否知曉或天真。
因為Airflow使用時區感知日期時間對象。 如果您的代碼創建了datetime對象,那么他們也需要注意。
```
from airflow.utils import timezone
now = timezone . utcnow ()
a_date = timezone . datetime ( 2017 , 1 , 1 )
```
### 解釋天真的日期時間對象
盡管Airflow完全可以識別時區,但它仍然可以在DAG定義中為<cite>start_dates</cite>和<cite>end_dates</cite>接受天真的日期時間對象。 這主要是為了保持向后兼容性。 如果遇到天真的<cite>start_date</cite>或<cite>end_date,</cite>則應用默認時區。 它以這樣的方式應用,即假定天真日期時間已經在默認時區。 換句話說,如果您有<cite>歐洲/阿姆斯特丹</cite>的默認時區設置并創建<cite>日期時間(2017,1,1)</cite>的天真日期時間<cite>start_date</cite> ,則假定它是2017年1月1日阿姆斯特丹時間的<cite>start_date</cite> 。
```
default_args = dict (
start_date = datetime ( 2016 , 1 , 1 ),
owner = 'Airflow'
)
dag = DAG ( 'my_dag' , default_args = default_args )
op = DummyOperator ( task_id = 'dummy' , dag = dag )
print ( op . owner ) # Airflow
```
不幸的是,在DST轉換期間,某些日期時間不存在或不明確。 在這種情況下,鐘擺會引發異常。 這就是為什么在啟用時區支持時應始終創建有意識的日期時間對象的原因。
實際上,這很少是一個問題。 Airflow可以讓您了解模型和DAG中的日期時間對象,并且通常,新的日期時間對象是通過timedelta算法從現有對象創建的。 通常在應用程序代碼中創建的唯一日期時間是當前時間,timezone.utcnow()自動執行正確的操作。
### 默認時區
默認時區是由<cite>[core]</cite>下的<cite>default_timezone</cite>設置定義的時區。 如果您剛剛安裝了Airflow,它將被設置為<cite>utc</cite> ,這是推薦的。 您還可以將其設置為<cite>系統</cite>或IANA時區(例如“歐洲/阿姆斯特丹”)。 DAG也在Airflow工作人員上進行評估,因此確保所有Airflow節點上的此設置相同非常重要。
```
[ core ]
default_timezone = utc
```
## 時區感知DAG
創建時區感知DAG非常簡單。 只需確保提供時區感知<cite>start_date</cite> 。 建議使用<cite>擺錘</cite> ,但也可以使用<cite>pytz</cite> (手動安裝)。
```
import pendulum
local_tz = pendulum . timezone ( "Europe/Amsterdam" )
default_args = dict (
start_date = datetime ( 2016 , 1 , 1 , tzinfo = local_tz ),
owner = 'Airflow'
)
dag = DAG ( 'my_tz_dag' , default_args = default_args )
op = DummyOperator ( task_id = 'dummy' , dag = dag )
print ( dag . timezone ) # <Timezone [Europe/Amsterdam]>
```
### 模板
Airflow在模板中返回時區感知日期時間,但不會將它們轉換為本地時間,因此它們保持UTC。 由DAG來處理這個問題。
```
import pendulum
local_tz = pendulum . timezone ( "Europe/Amsterdam" )
local_tz . convert ( execution_date )
```
### Cron安排
如果您設置了cron計劃,Airflow會假定您始終希望在同一時間運行。 然后它將忽略日光節省時間。 因此,如果您有一個時間表,表示每天在格林威治標準時間08:00 + 1的間隔結束時運行,它將始終在08:00格林尼治標準時間+ 1的間隔結束時運行,無論日間節電時間是否到位。
### 時間增量
對于具有時間增量的計劃,Airflow假定您始終希望以指定的間隔運行。 因此,如果您指定timedelta(hours = 2),您將始終希望運行數小時。 在這種情況下,將考慮日光節省時間。