What ISO 8601 is
ISO 8601 is the international standard for writing dates and times as
text so that both humans and machines read them the same way regardless of locale. It
orders fields from largest to smallest — year, month, day, hour, minute, second — and
pads every field to a fixed width, which is why it sorts correctly as plain text without
ever being parsed. A Unix timestamp, by contrast, is not text at all: it
is a single integer counting seconds (or milliseconds) elapsed since
1970-01-01T00:00:00Z, the Unix epoch. Converting between the two means
parsing the readable ISO 8601 string into an instant, then measuring the distance from
that instant back to the epoch.
Reading the format
A full ISO 8601 timestamp — 2026-08-18T12:00:00.123+05:30 — breaks down into
six parts:
| Segment | Example | Meaning |
|---|---|---|
YYYY-MM-DD |
2026-08-18 |
Calendar date — year, month, day, always zero-padded |
T |
T |
Literal separator between the date and the time of day |
HH:mm:ss |
12:00:00 |
24-hour time, zero-padded to two digits per field |
.sss |
.123 |
Optional fractional seconds — any number of digits |
Z |
Z |
UTC, short for the zero offset +00:00 |
±HH:MM |
+05:30 |
Numeric offset from UTC, used instead of Z for local times |
ISO 8601 vs RFC 3339
RFC 3339 is the internet-facing profile of ISO 8601: it is what HTTP
headers, JSON APIs and log timestamps almost always mean when they say "ISO 8601". RFC
3339 requires the parts ISO 8601 leaves optional — a full date, a full time, and an
explicit offset (Z or ±HH:MM) — while dropping the
features RFC 3339 has no use for, such as ISO 8601's week-date notation
(2026-W34-2) and duration syntax (P3Y6M). In practice, almost
every timestamp you will ever convert satisfies both standards at once, which is why
this page — and the searches for "iso 8601 unix" and "rfc3339" that bring people here —
treat them as the same target format.
Conversion examples
| ISO 8601 / RFC 3339 | Unix seconds | Unix milliseconds |
|---|---|---|
1970-01-01T00:00:00Z |
0 | 0 |
2026-08-18T12:00:00Z |
1787054400 | 1787054400000 |
2026-08-18T12:00:00.123Z |
1787054400 | 1787054400123 |
2026-08-18T17:30:00+05:30 |
1787054400 | 1787054400000 |
2026-08-18 (date only, midnight UTC) |
1787011200 | 1787011200000 |
The third and fourth rows land on the same Unix second as the second row — a fractional
part refines the millisecond value without changing the second, and an offset of
+05:30 on a later clock time describes the exact same instant as
Z on an earlier one.
How the timezone offset changes the result
A Unix timestamp has no timezone — it is a count of seconds since one fixed instant, full
stop. The offset in an ISO 8601 string exists purely to let you write a local
clock reading and still pin down that same instant unambiguously.
2026-08-18T17:30:00+05:30 and 2026-08-18T12:00:00Z convert to
the identical Unix timestamp because +05:30 means "five and a half hours
ahead of UTC" — subtract that offset and both strings describe noon UTC. Drop the offset
entirely, as in 2026-08-18T12:00:00 with no Z and no
±HH:MM, and the string becomes a local time with an unspecified zone:
some parsers assume UTC, others assume the machine's local timezone, and the resulting
Unix timestamp can differ by hours depending on which parser reads it. Always include
Z or a numeric offset when the exact instant matters. Working out which
offset a named zone was actually running on a given date — daylight saving included — is
the job of the UTC-to-local timezone converter.
Converting in code
// JavaScript — ISO 8601 / RFC 3339 string to Unix time
const seconds = Math.floor(new Date('2026-08-18T12:00:00Z').getTime() / 1000)
const millis = new Date('2026-08-18T12:00:00Z').getTime()
# Python — datetime.fromisoformat parses RFC 3339 directly (3.11+)
from datetime import datetime
seconds = int(datetime.fromisoformat('2026-08-18T12:00:00+00:00').timestamp())
-- SQL — Postgres treats an ISO 8601 literal as a timestamptz
SELECT extract(epoch FROM '2026-08-18T12:00:00Z'::timestamptz);
Going the other direction — Unix time back to an ISO 8601 string — is the same
new Date() and fromisoformat APIs run in reverse:
new Date(seconds * 1000).toISOString() in JavaScript, or
datetime.fromtimestamp(seconds, tz=timezone.utc).isoformat() in Python.
Common mistakes
-
Omitting the offset and assuming UTC. A bare
2026-08-18T12:00:00is not guaranteed to parse as UTC — some environments read it as local time instead, silently shifting the Unix timestamp by your timezone's offset. -
Treating
Zas optional decoration. It is the entire timezone declaration. Strip it and the string's meaning changes even though it still looks well-formed. -
Truncating fractional seconds by mistake. Unix milliseconds keep only
three digits of sub-second precision; a nanosecond-precision ISO 8601 string (
.123456789) needs to be handled by whatever produced it if that precision matters downstream — converting to Unix milliseconds necessarily rounds it away. - Mixing up seconds and milliseconds after conversion. The same failure mode that produces dates stuck in 1970 happens just as easily on the way out of an ISO 8601 parse as on the way in.
Frequently asked questions
What is ISO 8601?
ISO 8601 is an international standard for representing dates and times as text, in the
form YYYY-MM-DDTHH:mm:ss.sssZ. It orders fields from largest to smallest, is
zero-padded, and uses a literal T to separate the date from the time and a
Z (or a numeric offset like +05:30) to mark the timezone.
What is the difference between ISO 8601 and RFC 3339?
RFC 3339 is a stricter internet-facing profile of ISO 8601. ISO 8601 allows options RFC 3339 forbids, such as omitting the timezone entirely, using week-numbers, or representing durations. Almost every timestamp you meet in an API or a log file — including the ones this page parses — is valid under both standards.
How do I convert an ISO 8601 timestamp to a Unix timestamp?
Parse the string into a date-time value using your language's ISO 8601 parser —
new Date() in JavaScript, datetime.fromisoformat() in Python —
then read the number of seconds (or milliseconds) elapsed since 1970-01-01T00:00:00Z.
Paste a timestamp into the converter above to see both values immediately.
Does the Unix timestamp change if the ISO 8601 string has no timezone offset?
Yes. An ISO 8601 string with no Z and no numeric offset is a local time with
an unspecified zone, and different parsers resolve it differently — some assume UTC,
others assume the host machine's local timezone. Always include Z or an
explicit +HH:MM offset when the exact instant matters.
What is the ISO 8601 representation of the Unix epoch?
The Unix epoch — Unix timestamp 0 — is 1970-01-01T00:00:00Z in ISO 8601. Every Unix timestamp is a count of seconds (or milliseconds) offset from that instant; negative values represent dates before 1970.
Where to go next
Not sure whether a bare number you already have is seconds or milliseconds? The digit-count detector answers that in one paste. Converting a whole column of ISO 8601 values at once? The bulk converter handles the entire list without splitting it first.