调度时区处理

调度时区决定 cron 表达式的解释基准:调度器按 UTC 运行而表达式按本地时间编写时,任务会整体偏移;跨时区团队要显式声明 DAG 时区。

三个层次的时区问题

调度时区决定 cron 表达式按哪个时区解释。常见故障都来自三层时区不一致:调度系统自身按 UTC 运行,DAG 或任务的时区设置决定 schedule 的解释基准,数据存储侧(数据库、数仓)又可能用另一套约定。三层不一致时的典型现象是任务整体偏移若干小时,或者报表里「某天的数据少了几个小时」。

基本信息

三层时区调度系统时区、DAG 与任务时区、数据存储时区
Airflow 要求start_date 必须是 timezone-aware,建议显式指定
核对方法看 DAG 详情页显示的 Next Run 时间是否符合预期
常见坑服务器用 UTC、报表按北京时间解读,差 8 小时

典型使用场景

  • 跨国团队协作:统一以 UTC 存储,按使用方时区展示
  • 日切任务:明确业务日期按哪个时区界定,避免跨天歧义
  • 夏令时地区:美国、欧洲部分地区的时钟跳变要专门验证
  • 调度器迁移:从本地时区迁到 UTC 时,历史 cron 语义需要复核
  • 排查数据缺失:先确认是时区偏移还是任务确实没跑

Airflow 指定本地时区

Airflow 指定本地时区
import pendulum
from airflow import DAG

local_tz = pendulum.timezone('Asia/Shanghai')
dag = DAG(
    'daily_orders',
    start_date=pendulum.datetime(2026, 1, 1, tz=local_tz),  # 明确时区,避免按默认解释
    schedule='0 2 * * *',                                   # 按 Asia/Shanghai 解释为凌晨 2 点
    catchup=False,
)
# 若调度器运行在 UTC,未指定时区的 start_date 会被当作 UTC,执行时间整体偏移

时区层级与影响

层级典型取值不一致的表现
调度系统UTC 或本地时区DAG 整体偏移若干小时
DAG 与任务Asia/Shanghai 等cron 解释基准与预期不符
数据存储多为 UTC报表按本地时间查询时少一段数据
业务日期定义按本地自然日跨天任务的归属日期出现分歧
服务器与数据库统一用 UTC、而报表按北京时间解读时,查数必须统一转换口径,否则会出现「同一天数据少 8 小时」这类看起来像丢数的问题。
夏令时切换地区在跳变当天可能出现任务被跳过或重复执行,涉及这些地区的调度必须单独验证,不能假设 cron 语义与时区无关。

易错点

  • 用 naive datetime 作为 start_date,会被按环境默认时区解释,不同环境行为不一致
  • 夏令时切换时区未做专门验证,跳变当天出现任务跳过或重复执行
  • 数据以 UTC 存储、报表按本地时间直读,跨天区间统计被截断
  • 业务日期按服务器时区动态计算,服务器时区一改,历史口径全部偏移

数据来源与参考

  • Apache Airflow 官方文档:Time Zones 处理说明
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌