airflow web ui 显示的“last run time”实际指 dag 数据区间(data interval)的起始时间,而任务日志和 dag 详情页中显示的时间则是数据区间的结束时间,二者天然相差一个调度周期,并非时区或配置错误。
在 Apache Airflow 中,“Last Run Time”这一字段常被误解为任务实际触发或完成的时间,但其本质是 DAG 的 data interval start(数据区间起始时间),而非执行时间戳(execution_date 在旧版本中已弃用,现统一由 data interval 定义)。Airflow 的调度模型基于数据驱动:每个 DAG 运行对应处理一段历史数据窗口,例如:
因此,您在首页看到的 “Last Run Time”(如 2025-05-10)是 data interval start;点击进入 DAG 页面后,顶部显示的 Execution Date 或日志中的 logical_date 默认展示的是 data interval end(即 2025-05-11),这正是您观察到“小时+1”(或日期+1)现象的根本原因——它反映的是同一调度周期的区间终点,而非 bug 或时区偏差。
✅ 验证方式(在 DAG 文件中添加调试逻辑):
from airflow import DAG
from airflow.operators.python import PythonOperator
from datetime import datetime, timedelta
def print_intervals(**context):
dag_run = context['dag_run']
print(f"Data Interval Start: {dag_run.data_interval_start}")
print(f"Data Interval End: {dag_run.data_interval_end}")
print(f"Logical Date (alias for start): {context['logical_date']}")
with DAG(
'debug_data_interval',
schedule_interval='0 0 * * *',
start_date=datetime(2025, 1, 1),
catchup=True,
) as dag:
task = PythonOperator(
task_id='print_intervals',
python_callable=print_intervals,
dag=dag
)? 注意事项:
(Airflow 默认将 logical_date 显示为 interval end 以对齐“该次运行所代表的数据截止点”);总结:这不是缺陷,而是 Airflow 数据时间模型的核心体现。理解 data interval 是掌握调度语义、正确设置 start_date、排查延迟/跳过问题的前提。建议在 DAG 文档中显式标注数据区间含义,避免团队误读。