A Unix timestamp is the number of seconds elapsed since 1970-01-01T00:00:00Z — UTC, no timezone, no leap-second adjustment in the canonical form. The tool above converts between Unix timestamps and human-readable date strings in your browser; nothing leaves your machine.
Seconds vs milliseconds
The single most common timestamp bug:
| Convention | Example | Used by |
|---|---|---|
| Seconds | 1735689600 | Unix time(2), most REST APIs, JWT iat / exp, cron, log files |
| Milliseconds | 1735689600000 | JavaScript Date.now(), Java System.currentTimeMillis(), many event-streaming systems |
| Microseconds | 1735689600000000 | Some database TIMESTAMP columns, kernel ftrace |
| Nanoseconds | 1735689600000000000 | Go’s time.Time, monotonic clocks, telemetry pipelines |
A timestamp’s magnitude tells you which it is:
- 10 digits → seconds (covers ~2001 to ~2286)
- 13 digits → milliseconds
- 16 digits → microseconds
- 19 digits → nanoseconds
If you’ve ever seen a date in 1970 in your logs, the most likely cause is a milliseconds timestamp parsed as seconds — 1700000000 parsed as ms is 1970-01-20T16:13:20Z.
What “epoch” means
The reference moment is called the Unix epoch: 1970-01-01T00:00:00Z. The choice was somewhat arbitrary (Ken Thompson and Dennis Ritchie picked it for the original Unix), but it’s now embedded in nearly every operating system, programming language, and database.
Other systems use other epochs: Windows FILETIME counts 100-nanosecond intervals from 1601-01-01; .NET DateTime counts ticks from 0001-01-01; classic Mac OS counted from 1904-01-01. Converting between epochs is straight subtraction once you know the offset.
The Year 2038 problem
A 32-bit signed integer holds Unix-second timestamps up to 2³¹ - 1 = 2147483647, which is 2038-01-19T03:14:07Z. After that, 32-bit time_t overflows to a negative number and wraps to 1901.
Most modern systems use 64-bit time_t, which doesn’t overflow until ~292 billion years from now. The remaining 2038 risk lives in:
- Embedded devices that ship with 32-bit time and aren’t easily updated.
- Database columns explicitly declared as 32-bit (some MySQL
TIMESTAMPcolumns, depending on version). - File formats with 32-bit timestamp fields (older
tar, some filesystem inode designs).
If your system handles dates after 2038, audit the actual storage type, not the language’s time type. A Java long is fine; a MySQL TIMESTAMP(11) is not.
ISO 8601 — the human-readable counterpart
ISO 8601 is the standard text format for dates and times:
2025-01-01T00:00:00Z ← UTC, "Z" = Zulu time
2025-01-01T00:00:00+00:00 ← same instant, explicit zero offset
2024-12-31T19:00:00-05:00 ← same instant, expressed in EST
2025-01-01 ← date only, no time
The T separates date from time. The trailing Z or ±HH:MM is the timezone offset from UTC. Always include it — a string like 2025-01-01 00:00:00 with no offset is ambiguous between local time and UTC, and parsers in different ecosystems guess differently.
The tool above accepts both formats and reports both representations.
Timezones are presentation, not storage
A Unix timestamp is always UTC by definition — it’s a count of seconds, no timezone. The timezone enters when you format that count for human display. 1735689600 is the same instant on every machine; it renders as 2025-01-01T00:00:00Z in UTC, 2024-12-31T16:00:00-08:00 in Pacific, 2025-01-01T09:00:00+09:00 in Tokyo.
Best practice: store UTC timestamps (or ISO 8601 strings with explicit offsets); convert to local time only at display time.
Leap seconds
Unix time is not a true count of physical seconds since 1970. When a leap second is inserted by the IERS (most recently 2016-12-31T23:59:60Z), Unix time conventions vary:
- POSIX says repeat the second —
23:59:59happens twice. This is what most servers do. - Smearing (Google, AWS, Cloudflare time servers) spreads the leap second over hours, so no second is repeated but seconds are slightly long during the smear window.
- TAI (atomic time) doesn’t smear and isn’t aligned with civil time.
For application use, treat leap seconds as a curiosity. They don’t affect the typical “convert between Unix time and a date string” workflow.
Common pitfalls
- Off-by-1000 errors between seconds and milliseconds — described above.
- Negative timestamps. Unix time before 1970 is negative. Some date libraries reject negatives; some treat them as the next-millennium.
- DST in stored timestamps. A wall-clock time of
2025-03-09T02:30:00 America/New_Yorkdoesn’t exist (the clock skips from 02:00 to 03:00 in DST spring-forward). Storing local times instead of UTC turns DST transitions into data corruption. - Sub-second precision loss. Converting nanoseconds to a JavaScript
Date(millisecond resolution) silently truncates. Pick the precision you need at the storage layer, not at conversion time.
For other developer tools, see the hash generator and JWT decoder — JWT iat and exp are both Unix-second timestamps and are the most common place developers run into them.