Epoch Converter

Convert a Unix timestamp to a readable date, or a date back to a timestamp. Seconds and milliseconds are detected automatically, output covers UTC, your local time, ISO 8601, RFC 2822 and plain relative language, and negative timestamps before 1970 work exactly as they should.

Current epoch

Timestamp to date

Ten digits is almost certainly seconds; thirteen is milliseconds. Negative values are instants before 1970 and are fully supported.

Enter a timestamp above.
Converted values will appear here.

Date to timestamp

Pick a date and press Convert to epoch.
The epoch value will appear here.

Try:

What Unix epoch time actually is

Unix time, epoch time and POSIX time all name the same thing: a count of seconds since 1970-01-01T00:00:00Z. It is deliberately the simplest possible representation of an instant — one integer, no time zone, no calendar, no formatting decisions. Right now that number is around 1.7 billion, and it grows by one every second.

The reason it dominates APIs, databases and log files is that it is unambiguous. A string like 03/04/2026 means March 4th to an American reader and April 3rd to almost everyone else, and 2026-03-04 09:00 means nothing at all until you know which zone it was written in. An epoch timestamp has none of those problems: it names a specific moment that every system on earth agrees about. Formatting into a human calendar is a display concern, and it happens as late as possible — ideally in the user's own browser, where their zone and locale are actually known.

Because the value counts from UTC, it never needs a zone of its own. "The timestamp is in UTC" is a slight misstatement that nevertheless captures the right instinct: there is exactly one correct instant for a given epoch value, and rendering it in Tokyo or Denver changes the wall-clock text but not the moment being described.

Seconds or milliseconds — the single most common bug

Unix time is defined in seconds, but a great deal of software counts in milliseconds instead. JavaScript's Date.now() returns milliseconds. Java's System.currentTimeMillis() returns milliseconds. Kafka, most JVM logging, and a long list of JSON APIs return milliseconds. Meanwhile date +%s, PHP's time(), Python's time.time() (as a float of seconds), Postgres extract(epoch from ...) and every JWT claim in RFC 7519 are in seconds. Mixing the two is the most frequent timestamp bug in existence, and it has an unmistakable signature:

SymptomCauseFix
Every date renders in January 1970Seconds were passed to something expecting millisecondsMultiply by 1000
Dates land around the year 55,000Milliseconds were passed to something expecting secondsDivide by 1000
A token is always expiredAn exp claim written in millisecondsJWT claims are seconds — use seconds
A cache entry never expiresA TTL compared against the wrong unitNormalise both sides at the boundary

The digit count is the quickest diagnostic, and it stays reliable for a long time. A current timestamp in seconds has ten digits and will until November 2286. In milliseconds it has thirteen. Microseconds — which appear in Postgres, in some tracing systems, and in Chrome's internal timers — have sixteen, and nanoseconds have nineteen. The converter above uses exactly this heuristic, and the unit dropdown lets you override it when you are working with a very old or very distant date where the digit count would mislead.

The durable fix is a naming convention. A field called expires invites the bug; fields called expires_at_s and expires_at_ms do not. Convert once, at the edge of your system, and keep one unit internally.

UTC versus local time

An epoch value has no zone, but the moment you render it you have chosen one. That choice is where the second family of timestamp bugs lives. The tool above shows both renderings side by side precisely so the offset is visible rather than assumed.

Three rules cover most situations. Store UTC. Server clocks, databases and log pipelines should all be in UTC, with no exceptions; a server whose local zone observes daylight saving will produce an hour of duplicated timestamps every autumn and an hour that never happened every spring. Transmit UTC. Send epoch integers or ISO 8601 strings with an explicit Z or numeric offset; a bare 2026-07-20T09:00:00 is a guess waiting to be made wrong. Render local. Convert to the viewer's zone in the client, where the zone is known.

Note that an offset is not a time zone. +02:00 tells you the difference from UTC at one instant; Europe/Berlin tells you the rules, including when that offset changes. If you are storing a future appointment — "9am on the first Monday of March next year" — an epoch value is the wrong representation, because a government may move the daylight-saving boundary in the meantime and the intended wall-clock time would shift. Store the local date, the local time and the IANA zone name, and compute the instant when you need it. For everything that already happened, epoch is exactly right.

The year 2038 problem

Traditional Unix systems stored time in a signed 32-bit time_t. The largest value that holds is 2,147,483,647, which arrives at 03:14:07 UTC on 19 January 2038. One second later the counter overflows into negative territory and the date reads 13 December 1901. This is the direct descendant of the Y2K problem, and unlike Y2K it is not a formatting issue that can be patched at the display layer — it is the storage width itself.

Modern 64-bit platforms widened time_t long ago and are safe for roughly 292 billion years. The exposure that remains is in the corners: 32-bit embedded devices and industrial controllers, filesystem and network protocol structures with a fixed 32-bit time field, database columns declared as INT rather than BIGINT, and binary formats that cannot be changed without breaking compatibility. MySQL's TIMESTAMP type is a well-known example — it tops out in 2038, while DATETIME does not.

The failure mode is already reachable today: any system computing a thirty-year expiry, a mortgage schedule or a long-lived certificate can cross the boundary now. Press the 2147483647 button above to see the exact instant, and if your storage is a 32-bit integer, that is the moment it stops working.

Leap seconds, and why the count is not really elapsed time

Earth's rotation is not perfectly regular, so UTC is occasionally adjusted by a leap second to stay in step with astronomical time. Twenty-seven have been inserted since 1972. Unix time, however, is defined such that every day contains exactly 86,400 seconds — which means a leap second has no representation in it at all. The counter simply repeats or stalls.

Two practical consequences. First, the difference between two Unix timestamps is not exactly the number of seconds that physically elapsed between them if a leap second fell in between; the gap is short by one second per leap. If you need true elapsed duration, use a monotonic clock (performance.now(), CLOCK_MONOTONIC), never wall-clock timestamps — a fact that also matters when timing requests in the API tester, where an NTP correction mid-request could otherwise produce a negative duration. Second, major cloud providers now "smear" leap seconds, spreading the adjustment over many hours so that no second is ever repeated. That keeps software happy at the cost of the clock being deliberately, slightly wrong for a day.

ISO 8601, RFC 2822 and choosing a format

When a timestamp has to be human-readable as well as machine-readable, ISO 8601 is the right default: 2026-07-20T09:12:00.000Z. It sorts lexicographically in chronological order, it is unambiguous, it carries an explicit zone, and every language can parse it. RFC 3339 is the stricter profile of ISO 8601 that internet protocols actually use, and it is what most JSON APIs mean when they say "ISO date".

RFC 2822Sun, 20 Jul 2026 09:12:00 +0000 — is the older email and HTTP style. You will still meet it in Date, Expires and Last-Modified response headers, where the format is fixed by specification and always expressed in GMT. If you are debugging caching behaviour, those header values and the epoch timestamps in your logs describe the same instants, and the HTTP headers reference covers which header expects which form. A mismatch there produces stale content or, when a clock is skewed far enough, a 412 Precondition Failed on a conditional request.

For anything that is not being read by a person, prefer the integer. It is smaller, it cannot be misformatted, and it does not tempt anyone into string comparison. Reserve formatted strings for the boundaries: logs, headers, and the screen.

Frequently asked questions

Is this epoch converter free and private?

Yes. Every conversion is arithmetic performed in this page. Nothing is uploaded, logged or stored.

Why does my date show as 1970?

You almost certainly passed seconds to something expecting milliseconds. A ten-digit value interpreted as milliseconds is about twelve days after the epoch. Multiply by 1000.

What is timestamp 0?

1970-01-01T00:00:00Z, the epoch itself. Seeing it in production usually means a field was null or unset and got coerced to zero rather than being genuinely set to 1970.

Can I convert dates before 1970?

Yes — they are negative numbers, and this converter handles them. Be aware that some databases and libraries reject negative epoch values, which is why historical dates are often better stored as plain calendar dates.

How precise is a Unix timestamp?

One second by definition. Milliseconds, microseconds and nanoseconds are all conventional extensions that multiply the same base value, so precision is entirely a matter of which unit the producing system chose.

Related tools and reference