Skip to content

Scheduled callbacks shift by 1 hour after DST transition without restart #2582

@hans-fischer

Description

@hans-fischer

What happened?

Description

AppDaemon does not correctly handle Daylight Saving Time (DST) transitions at runtime. After a DST change, all time-based scheduled callbacks (e.g. run_at, run_daily, run_at_sunset) fire with a 1-hour offset until AppDaemon is restarted.

Environment

  • AppDaemon version: 4.4.0
  • Python version: 3.x (container default)
  • OS: Alpine Linux (Kubernetes pod)
  • Timezone config: time_zone: Europe/Berlin in appdaemon.yaml, TZ=Europe/Berlin env var
  • HA Plugin: HASS

Steps to Reproduce

  1. Start AppDaemon before a DST transition (e.g. CET → CEST on last Sunday of March at 02:00)
  2. Let AppDaemon run continuously through the DST switch
  3. Observe scheduled callback execution times after the transition

Expected Behavior

Scheduled callbacks should fire at the correct local time after DST transitions. A callback scheduled for 22:30 local time should fire at 22:30 CEST.

Actual Behavior

After the CET → CEST transition (clocks move forward 1 hour), all scheduled callbacks fire 1 hour late. AppDaemon appears to cache the UTC offset at startup and does not update it when DST changes.

Evidence from logs (2026-03-29/30, CET→CEST transition at 02:00):

2026-03-29 23:30:00 INFO og_night_mode: Evening time reached (22:30), switching to night mode
2026-03-30 00:00:00 INFO alarm_changer: Setting alarm to armed_night: Scheduled night mode (23:00)
  • The "22:30" evening callback fired at 23:30 wall clock time (logged as 23:30 because log timestamps use the same stale offset)
  • The "23:00" alarm callback fired at 00:00
  • Both are exactly +1 hour off, matching the DST delta

Workaround

Restarting AppDaemon after the DST transition resolves the issue immediately, as the correct UTC offset is recalculated on startup.

Additional Context

  • The container's system clock correctly shows CEST after the transition (date returns CEST)
  • The TZ environment variable is set correctly
  • appdaemon.yaml has the correct time_zone: Europe/Berlin
  • The issue appears to be in AppDaemon's internal scheduler caching the UTC offset rather than recalculating it for each scheduled event

This affects any long-running AppDaemon instance that spans a DST boundary (twice per year in most of Europe).

Version

4.4.0

Installation type

Home Assistant add-on

Relevant log output

Relevant code in the app or config file that caused the issue

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    issueSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions