namest504 opened a new issue, #76520:
URL: https://github.com/apache/airflow/issues/76520
### Under which category would you file this issue?
Providers
### Apache Airflow version
3.3.2
### What happened and how to reproduce it?
I ran into this while using Airflow with `core.default_timezone =
Asia/Seoul` on a host whose OS timezone is UTC. I tried the new
`start_from_trigger=True` option on `DateTimeSensorAsync` (standard provider
1.21.0, #73928) and a sensor with a naive `target_time` kept waiting for a time
that was already in the past.
The docs say a naive datetime is read in `core.default_timezone`. That is
what happens when the sensor goes through a worker. It is not what happens when
it starts in the triggerer.
To reproduce, run with `TZ=UTC` and
`AIRFLOW__CORE__DEFAULT_TIMEZONE=Asia/Seoul`:
```python
import datetime
from zoneinfo import ZoneInfo
from airflow.sdk import DAG
from airflow.providers.standard.sensors.date_time import DateTimeSensorAsync
# Written at 05:34 UTC. Read as Asia/Seoul this is about 8 hours in the past.
NAIVE_TARGET = datetime.datetime(2026, 11, 5, 6, 34, 26)
AWARE_TARGET = NAIVE_TARGET.replace(tzinfo=ZoneInfo("Asia/Seoul"))
with DAG(dag_id="dt_sensor_tz_repro", schedule=None, catchup=False,
start_date=datetime.datetime(2026, 1, 1)):
DateTimeSensorAsync(task_id="naive_start_from_trigger",
target_time=NAIVE_TARGET, start_from_trigger=True)
DateTimeSensorAsync(task_id="aware_start_from_trigger",
target_time=AWARE_TARGET, start_from_trigger=True)
DateTimeSensorAsync(task_id="naive_via_worker",
target_time=NAIVE_TARGET, start_from_trigger=False)
```
All three tasks point at the same instant. After triggering the Dag:
| task | result |
|---|---|
| `aware_start_from_trigger` | success after 3 s |
| `naive_via_worker` | success after 5 s |
| `naive_start_from_trigger` | still `deferred`; its trigger log says `2965
seconds remaining; sleeping 60 seconds` |
The third task reads the naive value as UTC and sits in the triggerer for
about 50 minutes on a deadline that already passed. With the timezones the
other way round (OS `Asia/Seoul`, Airflow `UTC`) the same sensor fires 9 hours
early.
### What you think should happen instead?
A naive `target_time` should mean the same instant whether the sensor starts
on a worker or in the triggerer, so `naive_start_from_trigger` should succeed
right away like the other two.
I traced it to `DateTimeSensorAsync.__init__`. On Airflow 3.3+ it puts the
raw `target_time` into `start_trigger_args.trigger_kwargs`. Dag serialization
turns a datetime into `.timestamp()`, and for a naive datetime Python uses the
process timezone, not `core.default_timezone`. Before #73928 the operator
stored `self._moment` there, which was already localized, so the problem did
not exist.
Localizing a datetime `target_time` before it goes into `trigger_kwargs`,
while leaving strings alone so templates still render in the triggerer, fixes
it. I have the change with tests and will open a PR.
### Operating System
Ubuntu 24.04
### Deployment
Virtualenv installation
### Apache Airflow Provider(s)
standard
### Versions of Apache Airflow Providers
apache-airflow-providers-standard 1.21.0
### Official Helm Chart version
Not Applicable
### Anything else?
Not affected: aware datetimes, strings with or without an offset, Jinja
templates, and Airflow below 3.3 (that branch still stores `moment`). The
official image runs with both timezones at UTC, so this only shows up once
`core.default_timezone` is changed or the host is not on UTC.
### Are you willing to submit PR?
- [x] Yes I am willing to submit a PR!
### Code of Conduct
- [x] I agree to follow this project's [Code of
Conduct](https://github.com/apache/airflow/blob/main/CODE_OF_CONDUCT.md)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]