Dev.to WebDev 🛠 Dev 👁 1 📖 2 min read

The Unix Timestamp, Demystified (and the 1000 Bug That Bites Everyone)

A Unix timestamp is one of the most common things in software and one of the most quietly misunderstood. Let's fix that. What it actually is It's a single integer: the number of seconds since midnight UTC on

A Unix timestamp is one of the most common things in software and one of the most quietly misunderstood. Let's fix that.

What it actually is

It's a single integer: the number of seconds since midnight UTC on 1 January 1970 — "the epoch". No timezone, no formatting, just a count from one fixed point. That's why it's the ideal way to store and compare moments: two events order by comparing integers, with zero ambiguity about which timezone was meant.

The bug everyone hits: seconds vs milliseconds

Unix tools and most APIs use seconds. JavaScript's Date uses milliseconds. Mix them up and you're off by a factor of 1000 — a date in 1970, or in the year 52,000. You can tell them apart by size: a "now" timestamp is ~10 digits in seconds, ~13 in milliseconds. So detect and normalise:

const digits = String(Math.trunc(n)).length;
const ms = digits <= 11 ? n * 1000     // seconds
         : digits <= 14 ? n            // milliseconds
         : Math.round(n / 1000);       // microseconds

A Date is an instant, not a string

A Date wraps a single millisecond count — an absolute instant. Everything you see (UTC text, local time, ISO) is just a rendering of that one instant. You never "convert" the instant between timezones; you only choose how to display it.

const d = new Date(ms);
d.toISOString();  // 2025-07-01T12:00:00.000Z  <- store THIS
d.toUTCString();  // Tue, 01 Jul 2025 12:00:00 GMT

Local and relative time via Intl

The browser's Intl handles the messy parts for free:

Intl.DateTimeFormat().resolvedOptions().timeZone;   // "Asia/Kolkata"
new Intl.RelativeTimeFormat(undefined, {numeric:"auto"})
  .format(-3, "day");                                // "3 days ago"

Two famous gotchas

  • JavaScript months are 0-based. new Date(2025, 0, 1) is January. Off-by-one bugs live here.
  • The Year 2038 problem. Systems storing the timestamp in a signed 32-bit integer overflow at 2,147,483,647 seconds — 03:14:07 UTC on 19 January 2038 — and wrap to a negative date. The fix everywhere is 64-bit timestamps.

The golden rules

Store UTC (or epoch). Convert to local only for display. Never hand-roll date maths — leap seconds, DST, and timezone history will get you; lean on Date, Intl, and the modern Temporal API.

Try the live converter (auto-detects the unit, shows every format, ticks in real time):
https://dev48v.infy.uk/solve/day22-timestamp-converter.html

📰 Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.