Somewhere deep in almost every piece of software you use, dates aren't stored as "August 12, 2026." They're stored as a single, plain number — something like 1786598400. That number is a Unix timestamp, and understanding what it actually represents clears up a surprising number of confusing bugs.

The definition, in one sentence

A Unix timestamp is the number of seconds that have elapsed since midnight, January 1, 1970, UTC — a moment in computing history known as "the Unix epoch." That's it. No months, no days, no timezones baked in — just one continuously increasing number.

Why computers do this instead of storing "August 12, 2026"

The seconds vs. milliseconds trap

This is, hands down, the most common Unix timestamp bug in real software. Some systems (Unix/Linux conventions, most databases, most REST APIs) use seconds. JavaScript's Date.now() and many logging systems use milliseconds. Mix them up, and the results are dramatic and confusing:

// Treating a seconds-based timestamp as milliseconds:
new Date(1786598400)
// → January 21, 1970 — instead of the intended date roughly 56 years later

// Treating a milliseconds-based timestamp as seconds:
new Date(1786598400000 * 1000)
// → a date roughly 56,000 years in the future

A quick sanity check: today's date, as a seconds-based timestamp, is a 10-digit number. As milliseconds, it's 13 digits. If you're staring at a timestamp and the date looks wildly wrong, this mismatch is the first thing to check.

What about dates before 1970?

Unix timestamps can go negative to represent moments before the epoch. A timestamp of -86400 represents December 31, 1969. This is less commonly used in practice (most application data is about events after 1970), but it's fully valid, and most date libraries handle negative timestamps correctly.

The Year 2038 problem

Older systems stored Unix timestamps as a signed 32-bit integer, which can only represent values up to about 2.1 billion. That number of seconds after the 1970 epoch lands on January 19, 2038 — after which a 32-bit timestamp would overflow and wrap around to a negative number, effectively jumping back to 1901 as far as the system is concerned. This sounds like ancient history, but it's a real, documented concern for older embedded systems and legacy software that haven't moved to 64-bit timestamps, which push the same problem out to a date roughly 292 billion years from now — comfortably beyond anyone's planning horizon.

Converting a timestamp to something readable

Every mainstream programming language has a built-in way to convert a Unix timestamp into a structured date object, and from there into whatever display format you need. The general pattern:

// JavaScript
const date = new Date(1786598400 * 1000); // convert seconds to ms first
console.log(date.toISOString()); // 2026-08-13T00:00:00.000Z

Notice the multiplication by 1000 to go from seconds to milliseconds — a very common step when a seconds-based timestamp meets a milliseconds-expecting API, and a very common place to forget it.

Timestamps in JWTs and API responses

Unix timestamps show up constantly in API design: a JWT's exp (expiration) and iat (issued-at) claims are Unix timestamps in seconds, per the JWT specification. Many REST APIs use them for createdAt or updatedAt fields, though ISO 8601 date strings ("2026-08-12T14:30:00Z") are also extremely common in modern API design specifically because they're human-readable without any conversion step, at a small cost in verbosity.

The practical takeaway

Whenever you're handed a raw timestamp, check two things before doing anything else: is it in seconds or milliseconds, and is it being interpreted in the timezone you expect for display? Get those two details right, and Unix timestamps are one of the most reliable, unambiguous ways computers track time.

Frequently Asked Questions

Count the digits. A current-day timestamp in seconds is 10 digits long; in milliseconds, it's 13 digits. If a converted date looks wildly wrong (like the 1970s or a date tens of thousands of years away), a seconds/milliseconds mismatch is almost always the cause.
No, and this is exactly the point — a Unix timestamp represents one specific, unambiguous instant in time, the same instant everywhere on Earth. Timezone only comes into play when converting that instant into a human-readable calendar date and clock time for display.
Yes, negative Unix timestamps represent moments before January 1, 1970 UTC. They're valid and correctly handled by most modern date libraries, just less commonly encountered in everyday application data.
Systems storing Unix timestamps as a signed 32-bit integer can only represent dates up to January 19, 2038, after which the value overflows and wraps to a nonsensical date. Modern 64-bit systems aren't affected, but some older or embedded systems still are.