我想在气流中运行dag,其执行日期应在CET中,但是默认情况下AIRFLOW在UTC上运行。因此,如果我想在变量中使用TS或EXECUTION_DATE的值... UTC当前时间。如何获取CET时区的execution_date
答案 0 :(得分:1)
execution_date
是Pendulum对象。
您可以使用in_timezone()
方法转换UTC时间。
示例代码:
from datetime import datetime
from airflow import DAG
from airflow.operators.bash_operator import BashOperator
dag = DAG(
dag_id="example",
schedule_interval=None,
start_date=datetime(year=1993, month=8, day=31)
)
with dag:
echo_op = BashOperator(
task_id="exec_date_as_cst",
bash_command="echo {{ execution_date.in_timezone('CET') }}"
)
答案 1 :(得分:0)
有一个很酷的库,叫做arrow,可以用来将时间从一个时区转换为另一个时区
>>> import arrow
>>> utc = arrow.utcnow()
>>> utc
<Arrow [2018-12-15T20:50:33.156717+00:00]>
>>> local = utc.to('CET')
>>> local
<Arrow [2018-12-15T21:50:33.156717+01:00]>
仅内置库的方法
>>> import dateutil.parser
>>> import timedelta
>>> ts = "201812160105"
>>> date = dateutil.parser.parse(ts)
datetime.datetime(2018, 12, 16, 1, 5)
>>> cet_ts = ts + timedelta(hours=1) # UTC + 1 hour = CET
datetime.datetime(2018, 12, 16, 2, 5)
,如果您希望将其恢复为iso格式
>>> cet_ts.isoformat()
'2018-12-16T02:05:00'
编辑:
要转换为ISO 8601格式的字符串,可以使用以下命令
>>> ts = '2018-12-15T21:10:00+00:00'
>>> arrow.get(ts)
<Arrow [2018-12-15T21:10:00+00:00]>
只需将运行时间从UTC转换为CET即可
>>> utc.to('CET')
<Arrow [2018-12-15T22:10:00+01:00]>
答案 2 :(得分:0)
EXEC_DATE = "{{ (execution_date + macros.timedelta(hours=1)).strftime('%Y%m%d%H%M')}}"
这将使{{ts}}增加一个小时,并且会像CET一样工作:)
答案 3 :(得分:0)
在当前版本的Airflow(1.10.x)中,他们需要模块pendulum,因为对timezone aware scheduling的支持有限。
将TS
和EXECUTION_DATE
的宏值(iirc)设置为Airflow系统的UTC时区,因为当持久化到数据库并显示UI时,Airflow会将所有内容转换为该值。您可能已经期望在配置中进行更改:
[core]
default_timezone = utc
可能会影响此效果,但似乎只会影响对原始日期时间的理解(例如,如果将DAG start_date设置为Datetime(2018,12,25)
,则会假定它位于default_timezone
中)
您可以像这样在PythonOperator中的DAG中转换execution_date
:
import pendulum
desired_tz = pendulum.timezone("Europe/Amsterdam")
desired_tz.convert(execution_date)
因为execution_date
已经知道它是UTC,所以转换应该准确。请注意,这不会将其分配给任何内容,也不会更改execution_date
。
如果您使用当地时间(未知时区),会发生以下情况:
>>> import pendulum
>>> dtz=pendulum.timezone("Europe/Amsterdam")
>>> dtz
Timezone('Europe/Amsterdam')
>>> import datetime
>>> d=datetime.datetime.now()
>>> d
datetime.datetime(2018, 12, 17, 17, 36, 5, 435666)
>>> dtz.convert(d) # Notice unchanged
datetime.datetime(2018, 12, 17, 17, 36, 5, 435666, tzinfo=Timezone('Europe/Amsterdam'))
>>> d
datetime.datetime(2018, 12, 17, 17, 36, 5, 435666)
>>> dtz.convert(pendulum.timezone("UTC").convert(d)) # Notice changed
datetime.datetime(2018, 12, 17, 18, 36, 5, 435666, fold=1, tzinfo=Timezone('Europe/Amsterdam'))
>>> d # Notice change not assigned
datetime.datetime(2018, 12, 17, 17, 36, 5, 435666)
所以……我希望这会有所帮助,因为CET与UTC IIRC的偏移量可变。