Unix timestamp converter

Convert a Unix timestamp to a readable date in any time zone, and a date back to epoch.

Current Unix time
Detecting…
Input

What a Unix timestamp is

A Unix timestamp — also called epoch time or POSIX time — is a single number counting how many seconds have passed since 00:00:00 UTC on 1 January 1970, a moment known as the Unix epoch. Because it is one integer with no time zone, no calendar and no formatting, it is the format computers reach for whenever a moment in time has to be stored, sorted, compared or sent across a network. It is what sits behind the "created_at" column in your database, the "iat" and "exp" claims in a JWT, the mtime on a file, and the timestamps in almost every log file you will ever read.

The trade-off is that a bare number means nothing to a human. 1716197600 is a perfectly good instant, but you cannot tell at a glance whether it is last Tuesday or three years ago. That translation, in both directions, is what this tool does.

Seconds or milliseconds — the ambiguity that bites

The original Unix convention counts whole seconds, and that is what you get from date +%s in a shell, from PHP's time(), and from Python's time.time() once truncated. JavaScript, Java and many others count milliseconds instead: Date.now() returns a number a thousand times larger. Both are called "timestamps", and mixing them up is one of the most common date bugs there is.

The failure is quiet rather than loud. Read a milliseconds value as seconds and your date lands tens of thousands of years in the future; read a seconds value as milliseconds and everything collapses into January 1970. Neither throws an error — you simply get a wrong date that looks like a real one.

This tool guesses from the magnitude of the number and then tells you what it guessed, right next to the result. Today's epoch seconds are ten digits and today's epoch milliseconds are thirteen, so the guess is almost always right — but "almost" is not good enough for a value you are about to paste into a bug report, which is why the reading is always visible and always one click away from being switched.

Time zones, UTC and why "local" is slippery

A Unix timestamp has no time zone. It identifies an instant, and that same instant is simultaneously 09:33 in London, 11:33 in Jerusalem and 18:33 in Tokyo. A time zone is not part of the value; it is a lens you look at the value through.

That is why this tool shows several lenses at once. UTC is the neutral reference every server and log agrees on. Your local time is what your own device reports, shown with its zone name (such as Europe/Berlin) so you always know which lens produced it — the detection happens in your browser, so a visitor in Berlin sees Berlin time and a visitor in Tokyo sees Tokyo time. The third row is any zone you pick from the full IANA time zone database, which is the row you want when you are reading a log from a server that lives somewhere else.

  • UTC — the reference every system agrees on, and the right thing to store and log.
  • Local — the same instant as your device sees it, labelled with the detected zone.
  • A zone of your choice — for reading logs and traces from machines elsewhere.
  • ISO 8601 — the interchange text format, e.g. 2024-05-20T09:33:20.000Z.
  • Relative — "3 hours ago", for a quick sense of how recent something is.

Offsets are shown alongside each time (+03:00, -04:00) because they are not fixed: most zones shift by an hour for daylight saving, so the same zone can produce different offsets at different times of year. A date near a transition is exactly where hand arithmetic goes wrong.

Working with epoch time in practice

Every language and shell has its own way to produce and read epoch values. These are the ones worth remembering:

date +%s                         # shell: current time in seconds
date -d @1716197600              # shell (GNU): seconds back to a date
Date.now()                       # JavaScript: current time in MILLIseconds
new Date(1716197600 * 1000)      # JavaScript: seconds to a Date
time.time()                      # Python: seconds, as a float
datetime.fromtimestamp(1716197600, tz=timezone.utc)
SELECT EXTRACT(EPOCH FROM now()) -- PostgreSQL: seconds

A rule of thumb that avoids most date pain: store and transmit instants as UTC — either an epoch integer or an ISO 8601 string — and convert to a local zone only at the last moment, when you actually display it to someone. Formatting early is how a time zone bug gets baked into your data instead of staying in your view layer.

One more thing worth knowing: a signed 32-bit seconds counter runs out on 19 January 2038, the "Year 2038 problem". Modern systems use 64-bit values and are fine, but old embedded devices and legacy database columns are exactly where you might still meet it.

Frequently asked questions

How does it know whether my number is seconds or milliseconds?
From its magnitude: values below roughly 1e11 are read as seconds, larger ones as milliseconds. Today that cleanly separates ten-digit seconds from thirteen-digit milliseconds. The reading is shown next to the result and you can switch it with one click, so the guess is never hidden from you.
Which time zone counts as "local"?
The zone your own device reports, detected in your browser and shown by name so there is no doubt. It is your zone, not the site's — a visitor in Berlin sees Berlin time and a visitor in Tokyo sees Tokyo time.
Can I convert a date back into a timestamp?
Yes. The same field accepts both directions: type a number and you get a date, type a date such as 2024-05-20 or 2024-05-20T09:33:20Z and you get the epoch value back. There is no mode to switch.
Does it handle dates before 1970?
Yes. Timestamps before the epoch are simply negative — -86400 is 31 December 1969 — and negative values are accepted and converted normally.
Why does my timestamp show a different date than I expected?
Almost always one of two reasons: the seconds/milliseconds reading is not what you assumed (check the label and switch it), or you are comparing a UTC value against a local-time expectation. The tool shows both rows side by side so you can see which one it is.
What is the Year 2038 problem?
Systems that store epoch seconds in a signed 32-bit integer overflow on 19 January 2038 and wrap to a negative number, giving dates in 1901. Anything using 64-bit values — which is nearly everything modern — is unaffected, but legacy embedded systems and old database columns can still be at risk.
Is the timestamp I enter sent anywhere?
No. Parsing, conversion and formatting all run in your browser using the platform's own date and time zone support. Nothing you type ever leaves your device.