Unix Timestamp Converter_
Paste an epoch and read it as a date, or build a date and read it back as an epoch. Seconds, milliseconds, microseconds and nanoseconds are all accepted and the unit is detected by which reading lands in a plausible year — shown with every result, overridable when the guess is wrong. Output covers ISO 8601, RFC 2822, UTC, your local time and any IANA zone, each with its own copy button. Everything runs in this tab.
| Input | ISO 8601 (UTC) | Epoch seconds |
|---|
- Input
- An epoch number in seconds, milliseconds, microseconds or nanoseconds — or a date, typed the way you would say it. The unit is inferred from the magnitude and you can override the guess.
- Output
- The date in whichever timezone you choose, in every format worth having: ISO 8601, RFC 2822, a relative reading, and the codes Discord renders in each viewer’s own zone.
- Processing
- Converted in this tab. The current epoch on the page is your own clock, not a server’s, which is why it keeps ticking with the network off.
- Limits
- Anything beyond about ±275,760 years from 1970 is refused with the range named, because that is where a JavaScript date stops existing. Leap seconds are not in epoch time at all — the count simply skips them.
- No timezone inside
- An epoch number carries no zone. It is a count of seconds since one fixed instant, and every timezone in the world agrees on the number — the disagreement only starts when you turn it into text.
Reading epoch time without getting it wrong
What a Unix timestamp is, and why it starts in 1970
A Unix timestamp counts how many seconds have elapsed since 00:00:00 UTC on 1 January 1970, leap seconds excluded. Epoch time, POSIX time and Linux timestamp all name the same number; an epoch unix timestamp converter and a Unix timestamp converter are the same tool. The 1970 start line was simply a round, recent date when Unix was being built in the early 1970s, close enough that a 32-bit counter of tenths of a second would not run out during development. Nothing about the format is human-facing: no months, no zone, no separators, just an integer that sorts and subtracts correctly. Every difficulty people run into is in the translation — which unit the integer is counting, and which zone you render it for.
Seconds, milliseconds, microseconds, nanoseconds
For dates in this era each unit has a recognisable width: ten digits is seconds, thirteen is milliseconds (JavaScript's native unit), sixteen is microseconds (Python datetime, many databases), nineteen is nanoseconds (Go, Rust, protobuf). Counting digits is how most converters guess, and it fails on anything not from this era — 946684800000 is thirteen digits, the year 2000 in milliseconds, and a digit-counting reader hands you a date in the year 31969. This page instead interprets the value in all four units, keeps whichever reading lands between 1990 and 2100, and only falls back to digit width when that test cannot separate them. Whatever it picks is printed next to the result, and the Unit select overrides it.
The number has no timezone — the text you turn it into does
1735689600 is one instant, identical in Tokyo and Toronto. A zone appears only when that instant is formatted, which is why UTC and your local time are always shown and why the selector carries the full IANA list — "to EST", "to UTC" and the rest are that dropdown, not different timestamps. Going backwards is where it stops being symmetric: a wall clock is not an instant until you say which zone it was written in, and twice a year some of those wall clocks are lies. The date form resolves the zone you choose, and when daylight saving makes your local time nonexistent or ambiguous it says so and offers both candidate instants rather than silently choosing one.
Converting a date to a Unix timestamp in code
Every stack has a one-liner, and every one of them has a unit trap. JavaScript: Date.now() gives milliseconds, so seconds want Math.floor(Date.now() / 1000), and new Date(2026, 0, 15) is January because the month argument is 0-indexed. Python: time.time() returns float seconds, datetime.fromtimestamp(ts, tz=timezone.utc) reads one back. MySQL has FROM_UNIXTIME(ts) and UNIX_TIMESTAMP(dt); PostgreSQL to_timestamp(ts) and extract(epoch from dt); SQL Server has no epoch type at all and needs DATEADD(second, ts, '1970-01-01'). Excel has no epoch function and needs the arithmetic spelled out — =(A1/86400)+DATE(1970,1,1), then format the cell as a date. A shell does date +%s and date -u -d @1735689600. Discord accepts raw epochs directly: <t:1735689600:R> renders as a live countdown in each reader's own zone, and the Discord row above emits the codes ready to paste.
Which unit is this?
| Unit | Digits today | The same instant | Where it comes from |
|---|---|---|---|
| Seconds | 10 | 1735689600 | Unix tools, JWT exp/iat, most APIs and databases |
| Milliseconds | 13 | 1735689600000 | JavaScript Date.now(), Java, MongoDB, Kafka |
| Microseconds | 16 | 1735689600000000 | Python datetime, PostgreSQL internals, tracing spans |
| Nanoseconds | 19 | 1735689600000000000 | Go UnixNano(), Rust, protobuf Timestamp |
Widths hold for dates roughly between 2001 and 2286. Older values break the pattern, which is why the detector here tests for a plausible year first and reports the unit it settled on.
Seconds per period — for building expiry timestamps
| Period | Seconds | Added to an epoch |
|---|---|---|
| 1 minute | 60 | Short-lived one-time codes |
| 1 hour | 3600 | Typical access-token lifetime |
| 1 day | 86400 | The number worth memorising |
| 1 week | 604800 | Session and refresh-token windows |
| 30 days | 2592000 | A "month" only when nobody checks |
| 365 days | 31536000 | A "year" that drifts a day every leap year |
Anything longer than a week is safer as calendar arithmetic than as added seconds: months vary between 28 and 31 days and leap years add one. Build the date in the form above instead and let the zone rules apply.
Where epoch time bites
Seconds against milliseconds — the bug that still runs
A factor of 1000 in the wrong place throws no error. The output just lands in 1970 (milliseconds read as seconds) or tens of thousands of years out (seconds read as milliseconds), so the year on screen is the diagnostic. It surfaces wherever JavaScript’s milliseconds meet a Unix API’s seconds — including a JWT, where exp and iat are defined as seconds and a milliseconds value silently mints a token expiring in the year 56000.
The Year 2038 problem is a storage bug, not a calendar one
Signed 32-bit time_t stops at 2147483647 — 2038-01-19T03:14:07Z — and the next second wraps to December 1901. 64-bit platforms were fixed years ago; what is left is embedded firmware, old binary formats, and INT columns in databases that were sized before anyone thought about it. Convert 2147483647 above and the page names the boundary on sight.
Daylight saving makes some local times fake and others double
On the spring-forward night the skipped hour never existed: 02:30 is not a time you can convert. On the fall-back night one hour runs twice, so a single wall clock maps to two different epochs. Most converters pick one silently. The date form here names which case you hit and shows both instants for the ambiguous one.
Excel and Windows count from a different zero
An Excel serial date counts days from 1900, or from 1904 in old Mac workbooks, and includes a phantom 29 February 1900. A Windows FILETIME counts 100-nanosecond ticks since 1601. Neither is a Unix timestamp, and pasting one into an epoch field yields a confidently wrong date rather than an error.
Unix time has no slot for a leap second
A day is exactly 86,400 seconds by definition, so 23:59:60 — which really happens on the civil clock — cannot be represented. Real systems repeat or smear a second instead. The date form rejects second 60 for this reason rather than quietly rolling it over to the next minute.
Units, ranges, and how the parsing decides
- Units
- Seconds, milliseconds, microseconds, nanoseconds. Values of 16+ digits parse through BigInt, render at millisecond precision, and state the sub-millisecond remainder rather than dropping it
- Auto-detect
- The reading that lands in 1990–2100 wins; digit width (≤11 / 12–14 / 15–17 / ≥18) only breaks ties. Always displayed, always overridable
- Timezones
- The browser’s own IANA data through
Intl, defaulting to your zone with UTC always alongside. No timezone database is shipped or fetched - Date → epoch
- Calendar-validated including leap years; the chosen zone is resolved against its real offset, and DST gaps and folds are reported with both candidate instants
- Range
- Negative epochs (pre-1970) through the JavaScript Date envelope of ±275,760 years; anything beyond it is refused with the limit named
- Batch
- Up to 1,000 non-blank lines per run, units mixed, per-line errors, CSV copy of input, ISO and seconds
- Network
- None from tool code. A test sweep calls every function this page uses with
fetchandXMLHttpRequestreplaced by stubs that throw, so a stray request fails the build instead of shipping. Disconnect from the network and the page still works.
Questions about epoch time and timezones
How do I get the current Unix timestamp?
The strip at the top of this page ticks it once a second with a copy button, in seconds and milliseconds. In code: Math.floor(Date.now() / 1000) in JavaScript, int(time.time()) in Python, date +%s in a shell — remembering that Date.now() is milliseconds.
What is the year 2038 problem?
Timestamps stored in a signed 32-bit integer overflow at 2147483647 seconds, which is 2038-01-19T03:14:07Z, and wrap round to 1901. Anything running 64-bit time is already safe; the exposure is in embedded devices, fixed-width file formats and INT database columns.
Can I convert a whole column at once?
Yes — the Batch tab takes up to 1,000 lines, detects each line’s unit independently so a mixed export still works, and copies the results back out as CSV. Lines it cannot read report their own error instead of stopping the run.
Why does my converted date land in 1970 or the year 56000?
Both are the seconds-against-milliseconds mistake, seen from its two sides: a 1970 date means a milliseconds value was read as seconds, and a far-future date means the reverse. Set the Unit select explicitly and the reading corrects itself.