What is a Unix timestamp?
A Unix timestamp (also called epoch time, POSIX time, or Unix time) is the number of seconds that have elapsed since 00:00:00 UTC on 1 January 1970 — the moment computers agreed to call "zero". That instant is known as the Unix epoch.
Right now, somewhere around 1,780,000,000 seconds have passed since then. That integer is what your database stores, what your API returns in a created_at field, and what your logs print when something happens. It looks cryptic, but it solves a real problem: a plain number has no timezone, no locale, no formatting — it is the same instant everywhere on Earth.
Why developers use timestamps instead of dates
- Sorting is trivial — bigger number = later. No date parsing required.
- No ambiguity —
03/04/2026means March 4th or April 3rd depending on where you are.1743724800means exactly one instant, everywhere. - Arithmetic works — "90 days from now" is
now + 90 * 86400. Try that with a formatted date string. - Storage is compact — one integer column instead of a timezone-aware datetime type (which your database may or may not handle correctly).
Seconds vs milliseconds: the #1 mistake
Not every system agrees on the unit:
| System | Unit | Example value for Sep 2026 |
|---|---|---|
Unix / Linux date +%s, PHP time() | seconds | 1789836000 |
JavaScript Date.now(), Java System.currentTimeMillis() | milliseconds | 1789836000000 |
| .NET ticks, some telemetry systems | 100-nanosecond ticks | 6387... (much longer) |
The classic bug: a backend stores seconds, a frontend calls new Date(value) — which expects milliseconds — and every date renders as January 1970. If your dates all show 1970, multiply by 1000. If they show the far future, divide by 1000.
Quick sanity check: a seconds timestamp is 10 digits (until the year 2286); a milliseconds timestamp is 13 digits. If you see 10 digits, it's seconds.
Converting timestamps: the fast way
The fastest, safest conversion — paste the value into the Unix Timestamp Converter and read the result in UTC and your local timezone at the same time. Seeing both at once is the point: it makes timezone bugs visible instead of invisible.
In code, the conversion looks like this:
// Timestamp → Date (value in seconds!)
const date = new Date(1789836000 * 1000);
// Date → timestamp (seconds — drop the milliseconds)
const ts = Math.floor(Date.now() / 1000);
# Linux / macOS
date +%s # now, in seconds
date -d @1789836000 # timestamp → human date
date -j -f %s 1789836000 # (macOS/BSD variant)
Sponsored
Timezones: why your +2 hours keep disappearing
A timestamp is timezone-free — it always means the same absolute instant. Timezones only appear when you display the value:
1789836000is 2026-09-19 16:40 UTC — simultaneously 17:40 in Lisbon (summer), 18:40 in Berlin, and 12:40 in New York.- The same timestamp formatted with different timezone settings produces different clock times, and that is correct behaviour.
The dangerous part is local time parsing. When a user types 2026-09-27 12:00 and your code parses it with the browser's timezone but stores it as if it were UTC, you have silently shifted every appointment by the user's UTC offset. The fix is discipline:
- Store timestamps (UTC, seconds or milliseconds).
- Convert to local time only for display.
- Never parse a wall-clock string without knowing which timezone it belongs to.
Daylight saving time: the 25-hour day
Timezones are bad enough; daylight saving makes them irregular:
- Some days have 23 or 25 hours. "Add 24 hours" and "add 1 day" are not the same operation.
- Two clocks per year are ambiguous or impossible (the repeated hour in autumn, the skipped hour in spring).
- Scheduling logic that assumes fixed daily offsets will drift — this is why cron-style systems (see the Cron Expression Generator) work in local wall-clock time while timestamps work in absolute time. They are different tools for different questions: "run at 09:00 every weekday" is a wall-clock question; "7 days after this event" is an absolute-time question.
The year 2038 problem
Most legacy systems store the timestamp in a signed 32-bit integer, which overflows on 19 January 2038 at 03:14:07 UTC. After that moment, 32-bit timestamps wrap around to 1901 — planes get unscheduled, subscriptions expire in the past, security certificates invalidate.
Modern 64-bit systems (every phone and laptop sold this decade) are unaffected — the limit moves to roughly 292 billion years. The risk lives in embedded devices, industrial controllers, and old databases with 32-bit integer columns. If you maintain such a system, migrating those columns to 64-bit is the fix, and the deadline is closer than it looks.
Common pitfalls checklist
- Unit mismatch — seconds vs milliseconds. Check digit count (10 vs 13) before converting.
- Parsing without a timezone —
2026-09-27alone is interpreted differently across languages (UTC in some, local in others). Be explicit. - Floating-point timestamps —
1789836000.123truncates differently per language. Prefer integers. - Client clocks lie — never trust
Date.now()on the client for authorization or ordering; use server time. - Copying test values — a "current timestamp" from a tutorial is years stale; generate a fresh one from the Unix Timestamp Converter when testing.
Timestamps reward a small amount of discipline: keep one unit, store UTC, convert at the edge, and treat wall-clock time as a display concern. Get those four habits right and the whole class of "off by two hours, sometimes" bugs disappears.
Related free tools
Try these free online tools — all run in your browser with no sign-up.
Keep reading
More hand-written guides from the blog.