API timezone debugging checklist

Guide · updated 2026-11-09

Off-by-eight-hours bugs rarely come from “JavaScript Date is broken.” They come from mixed conventions: storing local time as if it were UTC, formatting UTC as local, or scheduling cron in a machine timezone nobody documented.

1. Write down the contract

2. Capture one failing example end-to-end

Pick a single event. Record: user-visible local time, API payload, DB stored value, and log line. Convert each to epoch seconds with a known tool so you compare integers, not strings.

3. Check the usual suspects

  1. Server OS timezone vs container timezone vs orchestrator TZ env.
  2. ORM silently dropping offsets.
  3. Cron or queue workers using host local time.
  4. Frontend formatting UTC with a local formatter (or the reverse).
  5. DST boundaries for the user’s zone—not yours.

4. Prefer epoch or explicit offsets in logs

Human strings without offsets are ambiguous in multi-region systems. Log epoch milliseconds alongside a single UTC ISO string when debugging.