Initializing, please wait a moment

Unix timestamps explained - epoch, ISO-8601, and timezones


Every server log, database row, and API response on the internet encodes “when something happened” in one of four formats: the Unix epoch (seconds or milliseconds), ISO 8601, or RFC 2822. If you’ve ever pasted a timestamp into Slack only to argue about which timezone it was in, this guide is for you. It covers what each format actually encodes, how to convert between them, and the three pitfalls that catch out even experienced developers.


Unix epoch: seconds since 1970-01-01 UTC

The Unix timestamp — also called “epoch time” — is the number of seconds that have elapsed since 00:00:00 UTC on 1 January 1970. That reference point is arbitrary but universal; every Unix-derived system (Linux, macOS, Android, iOS) and almost every programming language tracks time internally as a count from this moment.

A current-ish value: 1776495426 translates to 2026-04-18 12:17:06 UTC. There’s no timezone encoded in the number itself — it’s always UTC — which is both a strength (no ambiguity when two systems compare timestamps) and a trap (whatever converts the number to a human-readable string has to pick a timezone, and it usually picks the local one).


Seconds vs milliseconds: the first source of confusion

JavaScript, Java, and most modern language standard libraries default to milliseconds since the epoch, not seconds. That same moment — 2026-04-18 12:17:06 UTC — is 1776495426 in seconds (10 digits) but 1776495426000 in milliseconds (13 digits). A quick rule of thumb for sanity-checking a timestamp you received:

  • 10 digits → seconds (Unix command line, PHP, Python time.time(), Go).
  • 13 digits → milliseconds (JavaScript Date.now(), Java System.currentTimeMillis(), most JSON APIs).
  • 16 or 19 digits → microseconds or nanoseconds (specialized telemetry and scientific timing).

A 10-digit seconds value interpreted as milliseconds renders as a date in 1970 (50+ years too early). A 13-digit millisecond value interpreted as seconds renders as a date ~56,000 AD. Both errors are instantly visible once the timestamp is converted — use Convert Milliseconds to Date to sanity-check, or Get Current Time in Milliseconds to compare against now.


ISO 8601: the readable interchange format

ISO 8601 is a human-readable date-time format that also machines agree on. The canonical form looks like: 2026-04-18T12:17:06.520Z. Parts:

  • Date: 2026-04-18 (YYYY-MM-DD, always this order).
  • Separator: T (literal letter T between date and time).
  • Time: 12:17:06.520 (HH:MM:SS.sss, 24-hour).
  • Timezone: Z for UTC, or an offset like +07:00 / -05:30 for other zones.

ISO 8601 is unambiguous (no regional date confusion like 04-18 vs 18-04), sortable as a plain string (lexical order matches chronological order when the timezone is the same), and supported by every modern parser. If you control the API you’re building, prefer ISO 8601 strings over raw Unix epoch numbers — they carry the timezone explicitly, which removes a whole class of bugs.


RFC 2822: the legacy email and HTTP format

RFC 2822 (and the nearly identical HTTP-date from RFC 7231) looks like Sat, 18 Apr 2026 12:17:06 +0000. It’s the format you’ll see in email Date: headers, HTTP Last-Modified headers, and some older web APIs. It’s readable but not sortable as a plain string (the weekday prefix breaks lexical ordering), so systems increasingly return ISO 8601 alongside or instead of RFC 2822. When you need to generate RFC 2822 manually, use a library rather than building the string yourself — the weekday name and month abbreviation are locale-sensitive and easy to get wrong.


UTC vs local time: the root of most timestamp bugs

Unix epoch timestamps are always UTC; ISO 8601 strings can be UTC (Z) or any offset; RFC 2822 almost always carries an offset. But when a programme displays a timestamp, it usually converts to the local timezone of the machine doing the display.

This is fine for a single user but causes chaos in three scenarios:

  • Sharing a timestamp in chat. “The deploy happened at 14:00” is ambiguous — whose 14:00? Paste the ISO 8601 value (2026-04-18T14:00:00+07:00) or explicitly state the timezone.
  • Logs from multiple servers. Set every server to UTC. Always. Log aggregators and incident-response tooling assume UTC; mixing timezones in logs is the fastest way to misattribute a cause-effect chain.
  • User-facing schedules. Store the event time in UTC (or the event’s source timezone with explicit offset) and convert at display time. Do not store “7pm” with no timezone; “7pm” in one user’s session may be 4pm for another.

Three common pitfalls (and how to catch them)

1. Integer-vs-string timestamps in JSON. JavaScript’s JSON.parse will faithfully produce a number for 1776495426520 — but if the API returned the same timestamp as a string "1776495426520", any downstream code doing arithmetic on it will silently coerce. Always check the type before passing to new Date().

2. Month 0–11 in JavaScript Date. new Date(2026, 3, 18) is 18 April 2026, not 18 March 2026. Month is 0-indexed but day and year are 1-indexed. Prefer the ISO 8601 constructor (new Date("2026-04-18")) which follows the natural numbering.

3. DST transitions. On “spring forward” night, 2:30am local doesn’t exist; on “fall back” night, 1:30am happens twice. If your system stores local-time strings, these moments create impossible or duplicated timestamps. UTC storage eliminates the problem; Date libraries like Luxon or date-fns-tz handle the conversion explicitly.


Related tools


← Back to Utility Tools

Why trust these tools

  • Ten-plus years of web tooling. The freetoolonline editorial team has shipped browser-based utilities since 2015. The goal has never changed: get you to a working output fast, without an install.
  • Truly in-browser — no upload. Every file-processing tool on this site runs in your browser through modern Web APIs (File, FileReader, Canvas, Web Audio, WebGL, Web Workers). Your photo, PDF, audio, or text never leaves your device.
  • No tracking during tool use. Analytics ends at the page view. The actual input you paste, drop, or capture is never sent to any server and never written to any log.
  • Open-source core components. The processing engines underneath (libheif, libde265, pdf-lib, terser, clean-css, ffmpeg.wasm, and others) are public and audit-able. We link to each one in its tool page's footer.
  • Free, with or without ads. All tools are fully functional without sign-up. The Disable Ads button in the header is always available if you need a distraction-free run.