Unix Timestamps Explained: Convert With Examples
Table of Contents
`1711999999`. That's not a phone number or a serial code — it's a moment in time: March 31, 2024, at 23:59:59 UTC. One plain integer that unambiguously names a single second in history, readable by every programming language on earth, sortable as a number, and completely immune to the chaos of timezones, daylight saving, and date formats. That integer is a Unix timestamp, and once you understand it, half of all datetime bugs become obvious before they happen.
The other half come from the traps: seconds versus milliseconds, timezones applied twice, and a looming overflow in 2038 that still hasn't been fully fixed. Let's walk through all of it with real numbers.
What a Unix Timestamp Actually Counts
A Unix timestamp (also called epoch time) is the number of seconds elapsed since 00:00:00 UTC on January 1, 1970 — the "epoch." Not since your birthday, not since the app launched: since that one fixed moment. So `0` is midnight at the start of 1970, `86400` is exactly one day later (86,400 seconds in a day), and right now the timestamp is somewhere around 1.79 billion and climbing by one every second.
Why 1970? Because Unix was being built in the early 1970s and its engineers needed a convenient round starting point near the present. It stuck, and now it's the lingua franca of time in computing: databases store it, APIs exchange it, JWTs use it for `exp` and `iat`, and log files are full of it.
The beauty of the format is what it doesn't contain: no timezone, no daylight saving, no "is that March 4th or April 3rd" ambiguity. A timestamp names an absolute instant. Timezones only enter the picture when you display it to a human — the same timestamp renders as different wall-clock times in Karachi, London, and New York, but it refers to the same instant everywhere. Store and compare in UTC timestamps; convert to local time only at the display layer. That single discipline prevents an enormous class of bugs.
Seconds vs Milliseconds: The Trap That Breaks Everything
Here is the trap that has broken more integrations than any other datetime mistake: Unix timestamps are defined in seconds, but JavaScript's `Date.now()` returns milliseconds. Python's `time.time()` returns seconds (as a float). Java's `System.currentTimeMillis()` returns milliseconds. Go's `time.Now().Unix()` returns seconds; `.UnixMilli()` returns milliseconds. Every language made its own choice, and mixing them produces spectacular failures.
The failure mode is distinctive: you pass a millisecond timestamp where seconds were expected, and the date comes out tens of thousands of years in the future. `1728000000000` milliseconds interpreted as seconds is the year 56,744. Conversely, passing seconds where milliseconds were expected gives you a date in January 1970 — `1728000000` read as milliseconds is about 20 days after the epoch.
How to tell which one you're holding: count the digits. As of 2026, a seconds timestamp is 10 digits (around 1.79 billion); a milliseconds timestamp is 13 digits (around 1.79 trillion). Ten digits → seconds. Thirteen digits → milliseconds. This digit-counting trick resolves the ambiguity in about two seconds, and it's the first thing to check whenever a converted date looks insane. The Unix Epoch Timestamp & Timezone Converter handles both and labels which one it detected, which removes the guesswork entirely.
Timezones: The Other Trap
If seconds-vs-milliseconds is the loud trap, timezones are the quiet one — the code works, the tests pass, and then daylight saving starts and everything shifts by an hour.
The core rule: a Unix timestamp has no timezone. It's UTC by definition. Timezone bugs happen when code adds timezone interpretation where none belongs — parsing a timestamp as if it were local time, or converting twice. The classic double-conversion: a server stores UTC, an API serializes it with a `+05:00` offset, and the client applies the offset again, shifting every displayed time by five hours. If your times are wrong by exactly your UTC offset, something converted twice. If they're wrong by exactly one hour and it started recently, it's daylight saving.
Daylight saving deserves special mention because it's the reason "just store local time" is terrible advice. Local times are ambiguous (the hour that repeats when clocks fall back happens twice) and non-existent (the hour that vanishes when clocks spring forward never happens). UTC timestamps have neither problem. Store UTC, display local, and let a proper timezone library (not hand-rolled offset math) handle the conversion — offsets change with politics, and hardcoding `+5` will betray you eventually.
The 2038 Problem, Honestly
On January 19, 2038, at 03:14:07 UTC, the 32-bit signed integer holding seconds-since-1970 overflows: it wraps from 2,147,483,647 to negative 2,147,483,648, and systems still using 32-bit `time_t` will believe it's December 1901. It's Y2K's less-famous sequel.
How worried should you be? For anything running on a 64-bit system with a 64-bit time type — which is nearly all modern servers, phones, and desktops — not at all; 64-bit timestamps won't overflow for 292 billion years. The risk lives in embedded systems, old 32-bit hardware, legacy file formats, and databases with 32-bit integer columns storing timestamps. If you're starting a project in 2026, use 64-bit integers (or your database's native datetime type) and the problem simply doesn't exist for you. If you're maintaining a system with 32-bit time fields, the fix is migrating those fields — unglamorous, but straightforward, and much cheaper now than in January 2038.
A Practical Conversion Checklist
When you're converting timestamps day to day, run this mental checklist:
- Count the digits first. Ten digits means seconds, thirteen means milliseconds. Convert accordingly — multiply seconds by 1,000 for JavaScript, divide milliseconds by 1,000 for Unix tools.
- Confirm the timezone of the output. A converter showing UTC and your code expecting local time (or vice versa) produces "wrong by exactly the offset" results. Know which one you're looking at.
- Watch for negative timestamps. Dates before 1970 are negative numbers (`-86400` is December 31, 1969). Some older systems and parsers don't handle them — if pre-1970 dates come out wrong, this is why.
- Beware float precision. A millisecond timestamp as a 64-bit float loses precision past 2^53 — fine for now, but don't do arithmetic on timestamps in floats if you can avoid it. Integers are exact.
- Sanity-check with a known date. `0` → 1970-01-01, `946684800` → 2000-01-01, `1672531200` → 2023-01-01. If your pipeline converts these correctly, your logic is sound.
- Don't trust the field name. APIs label timestamp fields `created_at`, `timestamp`, `date`, `time` — the name tells you nothing about seconds vs milliseconds. Count the digits on a real value before writing a single line of parsing code.
For one-off conversions — reading a timestamp from a log, checking a JWT's `exp`, verifying what a date picker actually sent — paste it into the Unix Epoch Timestamp & Timezone Converter and get the human-readable date, the timezone-adjusted equivalents, and the seconds/milliseconds detection in one view.
Try it free — no sign-up
Run the numbers yourself in seconds. Everything happens in your browser.
Open the Unix Epoch Timestamp & Timezone ConverterFrequently Asked Questions
What is a Unix timestamp?
The number of seconds since 00:00:00 UTC on January 1, 1970 (the "epoch"). It's a timezone-free, unambiguous way to represent an instant in time, used by databases, APIs, JWTs, and log files across every major platform.
How do I tell if a timestamp is in seconds or milliseconds?
Count the digits: as of 2026, seconds timestamps are 10 digits (about 1.79 billion) and milliseconds timestamps are 13 digits (about 1.79 trillion). Ten digits → seconds; thirteen digits → milliseconds. JavaScript's `Date.now()` returns milliseconds; most APIs and JWT claims use seconds.
Why does my converted date show the year 56,744 or January 1970?
Year 56,744 means you fed milliseconds into something expecting seconds (the value is 1,000× too large). January 1970 means you fed seconds into something expecting milliseconds (the value is 1,000× too small). Multiply or divide by 1,000 to fix it — and count the digits first to confirm which direction.
Do Unix timestamps account for timezones or daylight saving?
No — and that's their strength. A timestamp names an absolute instant in UTC; timezones only apply when displaying it to humans. Store and compare timestamps in UTC, convert to local time at the display layer with a proper timezone library, and never store local wall-clock times as your source of truth.
What is the Year 2038 problem?
On January 19, 2038, 32-bit signed integers counting seconds since 1970 will overflow and wrap to negative, making affected systems think it's 1901. Modern 64-bit systems are immune. The fix for legacy systems is migrating 32-bit time fields to 64-bit — straightforward, just unglamorous.
Why do JWT tokens use Unix timestamps for exp and iat?
Because they're compact, unambiguous, and trivially comparable — checking `exp > now` is one integer comparison with no parsing, no timezones, and no format ambiguity. Just remember JWT timestamps are in seconds, a frequent source of bugs when generating them from JavaScript's millisecond clock.