A Unix timestamp counts seconds since 1970-01-01 00:00:00 UTC. It shows up in log lines, bigint database columns, JWT exp claims, and webhook payloads — and no human can tell what day 1735689600 is. This tool converts both directions: paste a number to see the instant it represents in your local zone and in any of 22 common time zones, or pick a date and time to get it back as seconds and milliseconds. A live current timestamp ticks at the top of the page, ready to copy.
How to use it
- The panel at the top shows the current Unix timestamp in seconds, refreshed once a second, with a copy button. The small line below it is that same instant in your browser's time zone.
- Paste a number into the Timestamp → Date field. Seconds versus milliseconds is detected automatically — there is no unit switch. Trimmed input of 10 characters or fewer is read as seconds, 11 or more as milliseconds, and the verdict appears above the results as "Auto-detected: Seconds / Milliseconds".
- The first result row, Local Time, uses your machine's zone. The format is always
YYYY-MM-DD HH:MM:SS— 24-hour, zero-padded. - The dropdown in the second row switches zones: UTC plus grouped Asia, Europe, America, and Oceania entries, 22 in total, defaulting to UTC. The
UTC+8/UTC-4/UTC+5:30suffix on each option is that zone's real offset at the instant you entered, not a hardcoded constant. - Date → Timestamp uses the browser's native date-time picker and returns both a seconds and a milliseconds value.
- Every row has its own copy button. Non-numeric input — a date string, for instance — shows "Invalid timestamp".
When it comes in handy
Turn a number in a log or database into a time
A created_at stored as bigint, an Nginx msec field, a Kafka record timestamp: during an incident all of these have to become wall-clock time before you can line up the sequence of events. Paste and read, no Python REPL required.
Check whether a token has actually expired
JWT iat, exp, and nbf are all epoch seconds. Decode the payload, paste exp here, and compare it against the live counter at the top of the page. It also makes an issuer with a skewed clock obvious immediately.
Reconcile a customer report across time zones
The customer says checkout failed "around nine in the morning" and your logs are in UTC. Paste a timestamp, switch the dropdown to their city, and you know what that UTC instant looked like on their side — and which window of log lines to pull.
Produce boundary values for queries and fixtures
Writing WHERE created_at >= ? or seeding a record at a specific moment: pick the date and time in the second panel and copy the seconds or milliseconds straight into your SQL, cron config, or seed file.
Limits and behavior
- Unit detection counts **characters**, not magnitude. Ten digits covers seconds from 2001-09-09 to 2286-11-20 and thirteen covers milliseconds over the same span, so the heuristic holds for everyday values — but the minus sign counts toward the length, so
-1000000000(11 characters) is misread as milliseconds and resolves to 1969-12-20 instead of 1938. For pre-1970 instants, multiply by 1000 yourself or work from the other direction. - Sixteen-digit microsecond timestamps — the default precision in Postgres, ClickHouse, and several tracing systems — are not recognized. They are treated as milliseconds and land tens of thousands of years in the future. Divide by 1000 before pasting.
- Values beyond the range JavaScript
Datecan represent (±8,640,000,000,000,000 ms from the epoch, roughly ±270,000 years) are not flagged as errors; the result row printsNaNinstead.0NaN-NaN-NaN NaN:NaN:NaNmeans you typed too many digits. - The Date → Timestamp side has no zone selector. The native
datetime-localcontrol is always interpreted in your machine's local zone, and its default precision is one minute, so the seconds field is always 00 and the output is always a multiple of 60. For second-level precision, work backwards from the other direction. - An epoch value has no time zone of its own.
1735689600is a single instant; the zone only decides whose clock you read it on. That is why one timestamp produces 22 different strings in the dropdown while still describing one moment. - Unix time excludes leap seconds — it assumes every day is exactly 86,400 seconds long. Subtracting two timestamps therefore does not give the number of SI seconds that actually elapsed (27 leap seconds have been inserted since 1972). Irrelevant for everyday conversion, wrong for precision timing or astronomy.
Frequently asked questions
Why is my date off by a factor of 1000 — stuck in 1970 or fifty thousand years out?
Seconds and milliseconds got mixed up. It is the single most common epoch bug. Date.now() in JavaScript and System.currentTimeMillis() in Java give milliseconds (13 digits); int(time.time()) in Python, time() in PHP, Unix() in Go, and most REST APIs and JWTs give seconds (10 digits). Reading milliseconds as seconds lands you around the year 56,000; reading seconds as milliseconds lands you in mid-January 1970. This tool guesses from the digit count, but your own code will not — putting the unit in the column name (expires_at_ms) saves real debugging hours.
What is the year 2038 problem, and does it affect this tool?
The largest 32-bit signed integer, 2147483647, corresponds to 2038-01-19 03:14:07 UTC. One second later it overflows to a negative number, which legacy systems render as 1901-12-13. This tool uses a JavaScript double, so it has no such ceiling — that is why it can reach hundreds of thousands of years. The exposure is downstream: 32-bit time_t in C, MySQL TIMESTAMP columns (valid only up to 2038-01-19), embedded devices, and older APIs. Store long-lived expiry dates in DATETIME, BIGINT, or a 64-bit time_t.
Why does London show UTC+0 sometimes and UTC+1 other times?
Daylight saving time. The offset in parentheses is computed live from Intl.DateTimeFormat with shortOffset for the exact timestamp you entered, not looked up in a fixed table. Paste a July timestamp and London reads UTC+1; paste a January one and it reads UTC+0. New York alternates between UTC-5 and UTC-4 the same way, while Taipei, Tokyo, and Kolkata never shift — and yes, Kolkata really is a half-hour offset at UTC+5:30.
Are there local times that do not exist, or that happen twice?
Yes, and it is the reason the two directions are not symmetric. In America/New_York, the hour from 02:00 to 02:59 simply does not exist on the spring-forward day, and 01:00 to 01:59 happens twice on the fall-back day, so one local string maps to two timestamps 3600 apart. Timestamp → local time always has exactly one answer; local time → timestamp has zero or two on those two days, and the browser picks one for you with no way to override it. In schedulers this shows up as a job that silently skips a run, or runs twice, on the DST changeover.
Can I paste an ISO 8601 string like `2026-07-30T12:00:00Z`?
No. The timestamp field accepts numbers only; a date string returns "Invalid timestamp". Use the Date → Timestamp picker below for that direction. Output is likewise fixed at YYYY-MM-DD HH:MM:SS — this tool does not emit ISO 8601 strings with T and Z.
The clock at the top flashed 1970-01-01 when the page loaded. Is that a bug?
No. The current time is deliberately read only after the browser mounts the component, so a server-rendered clock never disagrees with yours and forces a repaint. Until then the value is 0, which is the epoch itself. The first tick, under a second later, replaces it.