If you have ever built a "post this at 9am" feature, you have probably shipped at least one daylight saving time bug. Here are the rules I now follow for any scheduling code.
1. Store the user's intent, not just a timestamp
A user who says "every Monday at 9:00 in Berlin" means local wall-clock time. Store:
{ "local_time": "09:00", "tz": "Europe/Berlin", "rrule": "FREQ=WEEKLY;BYDAY=MO" }
Then compute the next UTC instant when you enqueue the job. If you only store a UTC timestamp, the post drifts by an hour after the clocks change.
2. Handle the gaps and overlaps
- Spring forward: 02:30 does not exist on that day. Move to the next valid minute.
- Fall back: 01:30 happens twice. Pick the first occurrence and document it.
3. One queue, many networks
When one post goes to several networks, keep a single scheduled job and fan out at publish time. Each network gets its own retry state, so a failed TikTok upload does not block the LinkedIn post.
4. Test with fixed clocks
Inject the clock into your scheduler and write tests for the two DST transition days of every time zone you support.
I ran into all of these while working on a social media scheduler that publishes to 11 networks. The same logic powers the per-network pages such as the tiktok scheduler and youtube shorts scheduler. If you are building something similar, start with rule #1 and most of the other bugs never appear.
Top comments (0)