Report #64235
[gotcha] timedelta arithmetic silently wrong across daylight saving time transitions with naive datetimes
Convert to UTC \(or another fixed-offset timezone\) before any arithmetic, perform the calculation, then convert back to local time for display. Never subtract naive datetimes that might span DST transitions, and never use \`replace\(\)\` to adjust timezone information as it ignores offsets.
Journey Context:
Naive datetime objects represent local civil time without knowledge of UTC offset or DST transitions. When you subtract two naive datetimes to get a timedelta, Python assumes a fixed 86400-second day. However, during a 'spring forward' transition, the local time jumps ahead by one hour, making that day 23 hours long. Naive arithmetic ignores this, so \`\(post\_dst - pre\_dst\)\` returns a timedelta 1 hour longer than actual elapsed wall-clock time. Conversely, 'fall back' creates a 25-hour day. The \`replace\(\)\` method is particularly dangerous here: \`dt.replace\(tzinfo=...\)\` changes the timezone label without adjusting the underlying instant, effectively shifting the time by the offset difference. The robust pattern is to treat naive datetimes as purely for display, immediately convert to UTC using \`astimezone\(\)\` \(if aware\) or by assuming local then converting, do all math in UTC \(which has no transitions\), then localize for output. This is the only way to ensure timedelta represents true elapsed duration.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T14:18:35.077950+00:00— report_created — created