Unix Timestamp Explained

Updated 2026-08-31 · 3 min read

What it is

A Unix timestamp counts the seconds elapsed since 1 January 1970 00:00:00 UTC. Because it is a single number in UTC, it removes time-zone ambiguity, which is why logs, databases, APIs and JWT exp claims all use it.

Seconds or milliseconds?

Count the digits: 10 digits is seconds (Unix, PHP, Python), 13 digits is milliseconds (JavaScript Date.now()), and 16 digits is microseconds. Mixing the two is the single most common date bug — a seconds value read as milliseconds lands in January 1970.

Time zones and storage

Store instants as UTC timestamps and convert only for display. Store future local events (a 9am meeting) as a local date-time plus a time-zone identifier, because political time-zone rules change and a fixed offset will drift.

The year 2038 problem

A signed 32-bit timestamp overflows on 19 January 2038. Modern systems use 64-bit values, but legacy databases, embedded devices and old integer columns still need auditing.

Recognising a timestamp on sight

Digit count is the fastest diagnostic, and it is worth memorising because it turns a confusing bug into a two-second identification:

Storing time correctly in a database

Use a type that carries an instant, not a wall clock: timestamptz in PostgreSQL, TIMESTAMP in UTC in MySQL, or a 64-bit integer of epoch milliseconds. Avoid storing formatted date strings — they cannot be indexed usefully, sort incorrectly across formats, and hide time-zone assumptions.

Store the moment something happened as UTC. Store a future local appointment as a local date-time plus an IANA zone identifier such as Africa/Casablanca, because governments change offsets and a stored UTC instant would silently shift the meeting for the user.

Time zones, DST and the hours that do not exist

Local time is not continuous. On a spring-forward day one hour never occurs, so a naïve local time in that window is invalid; on the autumn transition an hour repeats, so a local time there is ambiguous and maps to two different instants. Code that adds 86,400 seconds to "tomorrow at 9am" is wrong twice a year.

Do arithmetic on UTC instants for durations, and on zoned date-times for calendar operations like "the same time next week". Libraries such as Temporal, Luxon or java.time exist precisely because this is easy to get wrong by hand.

Leap seconds and clock drift

Unix time pretends leap seconds do not exist: on a leap second, the same timestamp value occurs twice, so time can appear to stand still or step backwards. Most operating systems now smear the extra second across a day instead, which keeps clocks monotonic at the cost of being slightly wrong for a few hours.

For measuring elapsed time inside a program, never subtract two wall-clock timestamps — NTP corrections can move the clock backwards. Use a monotonic source such as performance.now() instead.

Where 2038 still bites

The signed 32-bit overflow on 19 January 2038 is fixed in modern 64-bit systems, but the exposure lives on in places that rarely get audited: legacy database columns typed as 32-bit integers, embedded firmware and industrial controllers, binary file formats with fixed-width fields, and expiry calculations that add 20 years to today.

Anything computing a date more than a decade ahead is worth checking now, because a certificate or subscription expiring past the boundary fails today, not in 2038.

Convert a timestamp now

Use the Unix Timestamp Converter to turn epoch values into readable UTC and local dates, or a date back into a timestamp. To see the same value inside a token, pair it with the JWT Decoder.

Try the Timestamp Converter →Convert Unix timestamps (epoch seconds or milliseconds) to human-readable dates and back. Free online timestamp converter.

Frequently asked questions

Do Unix timestamps include leap seconds?

No. Unix time deliberately ignores leap seconds, so a leap second repeats the same timestamp value.

Can a timestamp be negative?

Yes — negative values represent moments before 1 January 1970.

How do I convert a timestamp in JavaScript?

Multiply seconds by 1000 and pass to new Date(ms); use toISOString() for UTC output and toLocaleString() for local display.

Why does my date show 1 January 1970?

A seconds value was interpreted as milliseconds, or the value was null/zero. Check the digit count first.

Should I store dates as integers or timestamptz?

Either works if you are consistent; timestamptz is more readable in queries, integers are simpler across languages.

More guides

How Many Words Is a 5-Minute Speech?A 5-minute speech is roughly 625–750 words at a normal speaking pace. See word counts for 1, 3, 5, 10 and 20-minute talks, plus how to check yours instantly.How to Validate JSON and Fix Common Syntax ErrorsLearn how to validate JSON and fix the most common errors: trailing commas, single quotes, unquoted keys, comments and unescaped characters — with examples.Base64 Is Not Encryption: What It Actually DoesBase64 is reversible encoding, not encryption. Learn what Base64 is for, when to use it, its 33% size cost, and safe alternatives for protecting data.How to Decode a JWT SafelyLearn what is inside a JSON Web Token, how to decode the header and payload, how to read exp and iat claims, and why decoding is not verification.