Europe changed clocks on Sunday, the US does it next Sunday. Check your scheduled posts
Every year I tell myself I'll remember this before it happens. Every year somebody pings me on a Monday asking why the 9am posts went out at 8. Europe moved clocks back on October 25. The US does it on November 1. So fo
Every year I tell myself I'll remember this before it happens. Every year somebody pings me on a Monday asking why the 9am posts went out at 8.
Europe moved clocks back on October 25. The US does it on November 1. So for one week the gap between, say, Madrid and New York is 5 hours instead of the usual 6, and anything that quietly assumed a fixed offset is now wrong by an hour. If you run scheduled jobs, social posts, newsletters, cron anything, this is the week it bites.
Small disclosure up front: I work on the team at ContentStudio, which is a social scheduling tool, so I spend more time than is healthy looking at timestamps. Nothing below is specific to our product though, it applies to n8n flows, a Google Sheet with Apps Script, a homemade Node cron, whatever you've got.
The bugs I keep seeing
1. Storing "9:00 +02:00" instead of "9:00 Europe/Madrid"
An offset is a snapshot. A timezone is a rule. If someone picked "every Tuesday 9am" back in September and you saved it as 09:00+02:00, it will now fire at 8am local, because Madrid is +01:00 since Sunday.
Store the IANA zone name next to the local time and compute the UTC instant for each run, not once at creation time.
// luxon
import { DateTime } from "luxon";
function nextRun(localTime, zone, fromUtc = DateTime.utc()) {
const [h, m] = localTime.split(":").map(Number);
let candidate = fromUtc.setZone(zone).set({ hour: h, minute: m, second: 0, millisecond: 0 });
if (candidate <= fromUtc.setZone(zone)) candidate = candidate.plus({ days: 1 });
return candidate.toUTC();
}
nextRun("09:00", "Europe/Madrid").toISO();
plus({ days: 1 }) in Luxon respects the zone, so it moves to 9:00 local tomorrow even across a DST change. Adding 24 hours in milliseconds does not. That one cost me an afternoon once.
2. Server cron in UTC, humans thinking in local time
0 7 * * * on a UTC box was "9am Madrid" all summer. Now it's 8am. Most cron implementations let you pin a zone (CRON_TZ=Europe/Madrid in some, a timezone option in node-cron and in n8n's workflow settings). If yours doesn't, schedule hourly and check local time inside the job.
3. The hour that happens twice
On fall-back night, 02:00 to 02:59 happens twice in Europe. A job scheduled at 02:30 local either runs twice or your library picks one. Usually harmless for a social post, very not harmless for "charge the card" or "send the weekly digest". Make jobs idempotent with a run key like jobId + localDate so the second one is a no-op.
4. The hour that doesn't exist
Spring forward is the opposite. 02:30 on the last Sunday of March in Madrid never happens. Decide what you do (skip, or shift to 03:00) on purpose instead of letting a library decide silently. I'd shift, most people scheduling a 2:30am post didn't mean "never".
5. Clients in one zone, the team in another
This one isn't really a code bug, it's a UI one. Agency person in Lisbon schedules for a client in Chicago. The picker shows Lisbon time, the client expects Chicago time, and for this one week the difference changed by an hour. Show the audience's zone next to the time, always. Something like "9:00 Chicago (15:00 your time)" saves a lot of awkward emails.
A quick audit you can do today
- grep your DB or sheet for anything stored with a raw offset (
+02:00,-04:00) that's meant to repeat - list scheduled items between now and Nov 2 that cross the US/EU gap and eyeball them
- check what zone your cron host and your n8n instance actually run in (it's often UTC and nobody remembers)
- if you have a "send at the same local time for each recipient" feature, test it with one EU and one US address this week, not next
None of this is new, people have been writing about it for twenty years. It just keeps happening because the bug only shows up twice a year and everyone forgets in between. Which is honestly a pretty good argument for writing a test that freezes time at 2026-10-25T00:30:00Z and 2026-11-01T05:30:00Z and leaving it in the repo forever.
Anyway. Go check your Tuesday 9am posts.
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.