Almost every bug in this space comes from confusing two different things: an instant — a specific, unambiguous point in universal time, like a Unix timestamp — and a wall-clock time — the number on a clock in some particular place, like "2026-03-08 2:30 AM," which means nothing on its own until you say whose clock. A timestamp is always an instant. A date-and-time string almost never is, unless it carries an explicit offset or zone with it.
Storing a wall-clock time instead of an instant
The single most common root cause: a column, a log line, or an API payload that stores 2026-03-08 14:00:00 with no timezone attached at all. At the moment it's written, everyone involved knows it means "2 PM in our server's zone." Six months later, after a server migration, a new teammate, or a query run from a different machine, that context is gone and the value is permanently ambiguous — there's no way to recover which instant it actually referred to. The fix is boring and effective: store an instant (UTC, or an epoch integer) everywhere data crosses a boundary, and only convert to a wall-clock time at the final moment it's displayed to a person.
Seconds vs. milliseconds
A Unix timestamp counts seconds since 1970-01-01T00:00:00Z; JavaScript's Date constructor expects milliseconds since the same epoch. Mix them up and you don't get an error — you get a silently wrong date three orders of magnitude off:
new Date(1700000000) // a real Unix timestamp, passed as-is
// => Tue Jan 20 1970 — not November 2023
new Date(1700000000000) // the same instant, correctly in milliseconds
// => Tue Nov 14 2023There's a reliable way to tell them apart at a glance without doing the math: a seconds-based timestamp for any date after 2001 has 10 digits, and the equivalent milliseconds value has 13. That digit-count check is exactly how a timestamp converter can auto-detect which unit you pasted in without asking.
The spring-forward gap
Daylight saving time doesn't just shift the clock — twice a year, it makes part of the wall-clock timeline stop being one-to-one with real instants.
clocks jump from 1:59:59 straight to 3:00:00 — the entire 2 AM hour never occurs
clocks repeat 1:00:00 through 1:59:59 — that wall-clock hour occurs twice, once in each UTC offset
In the spring-forward transition, an entire hour of wall-clock time is skipped — clocks jump straight from 1:59:59 to 3:00:00. A naive parser handed 2026-03-08 02:30:00 in a zone observing that transition has to guess, because that wall-clock time was never real: some libraries silently normalize it forward to 3:30, some throw, and some produce a UTC offset for the wrong side of the transition entirely.
The fall-back ambiguity
The fall-back transition is the opposite problem: an hour of wall-clock time happens twice, once in each UTC offset. 2026-11-01 01:30:00 in a zone observing that transition is genuinely ambiguous — it's a real, valid wall-clock time, but it corresponds to two different instants an hour apart, and nothing in the string itself says which one was meant. A correct converter has to pick a convention (usually the first occurrence) and document it, rather than silently guessing and getting it right only half the time.
Truncating an instant to "just the date"
An order placed at 11:30 PM on January 15th in New York is, in UTC, already 2026-01-16T04:30:00Z — January 16th. Truncate that UTC instant down to a bare date for a "which day did this happen" report, and the order silently moves to the wrong day for the customer who placed it, while looking completely correct to anyone checking the database in UTC. This is the same instant-vs-wall-clock confusion as the storage bug above, just surfacing at read time instead of write time: a date only means something relative to a zone, and truncating first, converting second throws that zone away before it can be applied.
Hardcoding a fixed offset instead of a zone name
UTC-5 is not the same thing as America/New_York, even though they agree for part of the year. New York is UTC-5 in winter and UTC-4 in summer under daylight saving; a fixed offset baked into a config file or a cron schedule quietly drifts an hour off twice a year. IANA zone names encode the rules for a location's offset over time — including the fact that those rules themselves occasionally change, since countries have adjusted or abolished their own daylight-saving policy within recent memory — which a single fixed number can never do.
Try it yourself
Unix Timestamp Converter auto-detects seconds vs. milliseconds by digit count and shows the ISO, UTC, local, and relative form of any timestamp side by side. Timezone Converter converts a wall-clock time in one IANA zone to any other, computing each zone's real UTC offset for that specific instant — including the DST transitions above — instead of assuming a fixed offset. Both run entirely in your browser. For the recurring-schedule half of this problem — what a cron expression means across zones, and the gotchas that come with it — see Understanding Cron Expressions.