azharizz opened a new issue, #70527:
URL: https://github.com/apache/airflow/issues/70527

   ### Under which category would you file this issue?
   
   Airflow Core
   
   ### Apache Airflow version
   
   Airflow 3.x
   
   ### What happened and how to reproduce it?
   
   Serializing a `dateutil.relativedelta` that uses absolute time fields set to 
`0` (e.g. `hour=0` for midnight) drops those fields. After the Dag is 
deserialized, the schedule no longer snaps to midnight and keeps the base 
datetime's clock time instead.
   
   Root cause is in `encode_relativedelta` 
(`airflow-core/src/airflow/serialization/encoders.py`):
   
   ```python
   encoded = {k: v for k, v in var.__dict__.items() if not k.startswith("_") 
and v}
   ```
   
   The `and v` filter treats every falsy value as "unset". That is correct for 
**relative** fields (`hours`, `days`, …), which default to `0`, but wrong for 
**absolute** fields (`hour`, `minute`, `second`, `day`, …), which default to 
`None`. For absolute fields, `0` is meaningful like e.g. `hour=0` means "snap 
to midnight".
   
   **Minimal repro:**
   
   ```python
   from datetime import datetime
   from dateutil.relativedelta import relativedelta, FR
   from airflow.serialization.serialized_objects import BaseSerialization
   
   delta = relativedelta(weekday=FR, hour=0, minute=0, second=0)
   base = datetime(2024, 1, 10, 15, 30, 45)
   
   print(base + delta)
   # expected: 2024-01-12 00:00:00
   
   round_tripped = 
BaseSerialization.deserialize(BaseSerialization.serialize(delta))
   print(base + round_tripped)
   # actual today:   2024-01-12 15:30:45  (hour/minute/second lost)
   ```
   
   Same bug hits any path that serializes intervals via `encode_relativedelta` 
/ `encode_interval` (Dag schedules, timetables, serialized deltas).
   
   Example Dag schedule that silently changes meaning after parse → serialize → 
scheduler:
   
   ```python
   from datetime import datetime
   from dateutil.relativedelta import relativedelta, FR
   from airflow.sdk import DAG
   
   with DAG(
       dag_id="example_friday_midnight",
       start_date=datetime(2024, 1, 1),
       schedule=relativedelta(weekday=FR, hour=0, minute=0, second=0),
       catchup=False,
   ):
       ...
   ```
   
   After serialization, the absolute `hour`/`minute`/`second` fields are gone, 
so runs are planned at the previous interval's wall-clock time instead of 
00:00:00.
   
   
   
   ### What you think should happen instead?
   
   This is for the example:
   Absolute fields with value `0` must survive the encode → decode round-trip. 
Relative fields that are `0` can still be dropped (they mean "unset").
   
   Expected encode for `relativedelta(weekday=FR, hour=0)`:
   
   ```python
   {"hour": 0, "weekday": [4]}
   ```
   
   not only `{"weekday": [4]}`.
   
   ### Operating System
   
   Debian
   
   ### Deployment
   
   Other
   
   ### Apache Airflow Provider(s)
   
   _No response_
   
   ### Versions of Apache Airflow Providers
   
   _No response_
   
   ### Official Helm Chart version
   
   main (development)
   
   ### Kubernetes Version
   
   _No response_
   
   ### Helm Chart configuration
   
   _No response_
   
   ### Docker Image customizations
   
   _No response_
   
   ### Anything else?
   
   _No response_
   
   ### 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]

Reply via email to