Unix Timestamp Converter
Convert epoch timestamps to human dates and back — unit auto-detected, exact to the nanosecond, entirely on this device.
Local and relative rows render in this zone; zone-less date strings are read in it and flagged inline. Cells beginning with =, +, -, @ or a tab get a leading apostrophe so spreadsheets treat them as text — negative epochs start with -. Turn off only when a strict parser needs raw cells.
The conversion appears here as you type — paste one value, or one per line for a batch.
Press ? for shortcuts
Do it offline:$ date -u -d @1784937600
How to use it
- Paste a timestamp or a date into the single field — the field itself decides the direction. Digits run epoch-to-date and produce the full table; anything date-shaped runs the reverse and returns epoch seconds and milliseconds side by side.
- Check the detection badge. It names the unit the digit count implies — seconds, milliseconds, microseconds or nanoseconds — and when the count could mean two units, both readings appear as ranked cards; the badge or a unit chip pins the one you meant.
- Pick the display zone. The Local row starts in your browser's own zone, any IANA zone from the selector re-renders the table in place, and a date string that carries no offset of its own is read in that zone, with a note saying so right where it happens.
- Take the result with you: every row carries its own copy control, Share folds the current state into the page link, and a multi-line paste becomes a per-row table with a CSV download.
Paste an epoch timestamp and read it as a date, or paste a date and get the epoch back — one field decides which way the conversion runs. The unit is detected from the digits themselves, seconds through nanoseconds, with an override one click away; a list of values converts line by line; and every conversion happens on this device, with nothing sent anywhere.
How it works
A Unix timestamp is a single count: the number of seconds since 1970-01-01T00:00:00Z, the instant engineers call the epoch. The count is zone-free by construction — two machines on opposite sides of the planet stamp one event with one number — which is why it became the interchange currency of logs, databases, cookies and cache headers. Rendering that count for humans is this page's whole job: the same instant comes back as ISO 8601 in the RFC 3339 internet profile, as the older RFC 2822 form that e-mail headers still speak, and as a wall-clock time in whichever IANA zone you select.
The four units differ only in magnitude, and magnitude shows up as digit count. A present-day epoch in seconds is 10 digits long; each finer unit multiplies by a thousand, so milliseconds occupy 13 digits, microseconds 16 and nanoseconds 19. Detection reads that band and names its verdict on the badge. The bands in between — 11 or 12 digits, 14 or 15, 17 or 18 — are genuinely ambiguous, so the page renders every plausible reading instead of picking one in silence.
JavaScript's own date arithmetic has edges worth knowing. ECMA-262 §21.4.1.1 limits a Date to ±8,640,000,000,000,000 milliseconds around the epoch — exactly ±100,000,000 days — and Number holds integers exactly only up to 2^53 − 1, a ceiling that a 16-digit microsecond count already crosses. This engine therefore carries every instant as a BigInt count of nanoseconds from parse to output, so 19-digit values keep their final digits instead of landing on the nearest representable double.
One thing epoch time deliberately ignores: leap seconds. POSIX defines every day as exactly 86,400 counted seconds, so when UTC inserts a leap second the tally does not grow an extra step — it effectively spends two real seconds on one value. That fiction keeps timestamp arithmetic simple, since midnight boundaries are always clean multiples of 86,400, at the price of being unable to name a leap second at all; the FAQ below covers what that means for measurements taken across one.
Examples
17849376002026-07-25T00:00:00ZTen digits, so the badge reads auto-detected: seconds. One paste yields the whole table — ISO 8601, RFC 2822, UTC, your local zone and a relative reading in plain words, each row with its own copy control.
17849376000002026-07-25T00:00:00ZThirteen digits, so the badge reads auto-detected: milliseconds — same instant as example 1, three zeros later. The pair is the detection rule made visible: magnitude alone separates the units.
01970-01-01T00:00:00ZThe Unix epoch itself — the zero the whole scheme counts from, midnight UTC at the start of 1 January 1970. Every other timestamp is a distance from this instant.
2026-07-25 09:00 +05:301784950200A date string flips the direction. The +05:30 offset places nine in the morning at 03:30 UTC, and the answer arrives as an epoch-seconds row, 1784950200, with its milliseconds sibling 1784950200000 directly beneath — APIs disagree about which of the two they expect.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
Negative numbers are dates too
The epoch is a zero point, not a floor. -86400 is exactly one day before it — 1969-12-31T00:00:00Z — and the page converts negative values without complaint because nothing is wrong with them: birthdates, archives and historical datasets live before 1970 as a matter of course. Treat a system that rejects them as the special case; the arithmetic itself runs clean to the ECMAScript range limit in both directions.
2038 is a note on this page, never an error
2147483647 — the largest signed 32-bit integer — converts to 2038-01-19T03:14:07Z, the instant legacy time_t counters roll over. When a seconds value lands within about six months of that boundary, an inline explainer appears so the number's significance is visible; the conversion itself proceeds normally, here and far beyond, because nothing about 64-bit or BigInt time ends in 2038.
Fractional seconds keep their fraction
A float such as 1784937600.5 is not truncated: the fraction rides along at nanosecond resolution, so the half second survives into the ISO 8601 row — 2026-07-25T00:00:00.500Z — and, in a batch, into the CSV's epoch_ms column as 1784937600500. Epoch floats come from profilers, packet captures and Python's time.time(), places where the fraction is the interesting part, and dropping it silently would change what the data says.
Eleven and twelve digits: both readings, ranked
The seconds band and the milliseconds band do not quite meet, and values of 11 or 12 digits fall in the gap: 178493760000 is either seconds in the year 7626 or milliseconds in August 1975. Detection neither guesses in silence nor stops to interrogate you — both interpretations render as ranked cards, and one click on a unit chip pins the reading for as long as the current input stands.
Sixteen and nineteen digits arrive intact
Beyond 2^53 − 1 = 9007199254740991, JavaScript's Number quietly rounds: read 1784937600123456789 as a float and you hold 1784937600123456768, twenty-one nanoseconds early. This converter parses microsecond and nanosecond timestamps as BigInt and keeps them that way end to end, so the ISO 8601 row keeps the full nine-digit fraction — 2026-07-25T00:00:00.123456789Z — and its copy button carries the exact instant, never the nearest double.
A date without a zone is read in the display zone — and says so
2026-07-25T09:00:00 names a wall-clock reading but no place on Earth, so it maps to a different instant in every zone. Rather than silently assuming UTC or silently assuming local, the page reads a zone-less string in the display zone currently selected and states that assumption inline, next to the result. Change the selector and the epoch value moves with it.
Leap seconds are invisible in epoch time
UTC has inserted 27 leap seconds since 1972; the epoch count acknowledges none of them. During an insertion the counter effectively holds one value for two real seconds, which is why two events a breath apart can carry identical second-resolution stamps across a leap-second midnight. A timescale that counts every physical second exists — TAI — but epoch time is not it, by design rather than by accident.
Common errors
Not a timestamp or a recognizable date — try 1784937600 or 2026-07-25T00:00:00Z- The parser walked its whole ladder — strict ISO 8601, then RFC 2822, then a constrained set of common date shapes — and nothing matched, and the text is not a plain number either. Anything that fails every rung lands here, in single-value and batch mode alike. Your input stays in the field, untouched, and the two shapes quoted in the message are always safe starting points.
Outside the representable range — ECMAScript dates cover ±8,640,000,000,000,000 ms around 1970-01-01T00:00:00Z (about 271821 BCE to 275760 CE)- The bound is ECMA-262 §21.4.1.1: a Date reaches at most ±100,000,000 days from the epoch. In practice this error almost always signals a unit mix-up rather than a genuinely prehistoric instant — a nanosecond count pinned as milliseconds overshoots the range a millionfold. Re-check the badge before re-checking the number.
Input is larger than the 50 MB limit for this tool. For bigger batches use the CLI: while read t; do date -u -d "@$t"; done < timestamps.txt- Past 50 MB the page declines the whole batch rather than converting an honest-looking prefix of it, and what you pasted is kept referenced so nothing is lost. A file of timestamps that size belongs on the command line anyway: the banner's loop feeds each line to GNU date on your own machine, with the same privacy this page offers.
Line 2: Not a timestamp or a recognizable date — try 1784937600 or 2026-07-25T00:00:00Z- In batch mode every line is its own conversion. A row that fails gets its message and its line number; the rows around it convert regardless, and the status line counts how many went each way. A batch never aborts on a bad row — the failure stays exactly as local as the mistake.
FAQ
What does a Unix timestamp actually count?
A count of seconds since 1970-01-01T00:00:00Z, with leap seconds left out of the tally. It is the closest thing computing has to a universal clock reading: one integer, no zone, no format, no argument about field order — and sorting the numbers sorts the events. The finer variants in milliseconds, microseconds and nanoseconds are the same idea from the same zero point, scaled by powers of a thousand.
Seconds or milliseconds — which one do I have?
Count the digits. Ten digits means seconds until the year 2286; thirteen means milliseconds for any present-day instant. By source: most Unix APIs and databases hand out seconds, JavaScript's Date.now() and Java's System.currentTimeMillis() hand out milliseconds, and kernel tracing leans toward nanoseconds. Eleven or twelve digits genuinely could be either, which is when this page lays out both readings and lets you pin one.
What actually happens in 2038?
At 2038-01-19T03:14:07Z the seconds count passes 2147483647, the ceiling of a signed 32-bit integer, and any system still storing time in one wraps to a negative number. Modern 64-bit time_t pushed that horizon out by hundreds of billions of years, and this converter does its arithmetic in BigInt, so here the moment is an annotation rather than a failure. The places worth auditing are embedded devices and old file formats.
Are negative timestamps valid?
Yes — a negative count is simply an instant before 1970, and the representable line stretches back to roughly 271821 BCE. Rejection of negative values is a limitation of particular systems, not a rule of epoch time; plenty of real data lives on that side of zero.
Does Unix time count leap seconds?
No. POSIX fixes the day at 86,400 counted seconds, so the leap seconds UTC has inserted never entered the count. Two practical consequences: subtracting stamps that straddle an insertion understates real elapsed time by one second, and no epoch value can name 23:59:60 itself. Measure critical intervals with a monotonic clock; use epoch time for naming instants.
How do I convert timestamps without this page?
On GNU/Linux, date -u -d @1784937600; macOS and the BSDs spell the flag differently — date -u -r 1784937600. In code, prefer the standard library to string arithmetic: Python's datetime.fromtimestamp(1784937600, tz=timezone.utc), JavaScript's new Date(1784937600000).toISOString(), Java's Instant.ofEpochSecond(1784937600), or C's strftime over gmtime. Each is the same subtraction from the same zero.
Keyboard shortcuts
- ⌘/Ctrl + Enter
- Run the conversion again immediately; for a large batch waiting behind the explicit-run threshold, this is the run itself.
- ⌘/Ctrl + S
- Download the result — the conversion table as .txt for a single value, the row table as .csv in batch. The help overlay notes that this overrides the browser's save-page shortcut.
- ⌘/Ctrl + C
- With focus in the tool and nothing selected, copy the primary output — the ISO 8601 UTC string for a timestamp, the epoch-seconds value for a date. A live selection copies just itself.
- ⌘/Ctrl + Shift + C
- Copy the primary output regardless of any selection.
- t
- Step to the next color theme (ignored while typing in any field, during IME composition, and when single-key shortcuts are disabled).
- ? or ⌘/Ctrl + /
- Open keyboard help, where browser-shortcut conflicts and the ticker's Pause control are documented.
- Esc
- Close whichever overlay is on top; the input is never cleared.