ISO 8601 Date Format Guide
ISO 8601 is the international standard for representing dates and times in a machine-readable, unambiguous format. If you have worked with REST APIs, database schemas, or log files, you have already encountered it — strings like 2026-05-28T14:30:00Z are ISO 8601 timestamps. This guide covers the format's structure, common patterns, and the pitfalls developers hit most often.
Basic Format Structure
ISO 8601 prescriptions follow a most-significant-to-least-significant order — year, month, day, hour, minute, second — which makes chronological and lexicographic sorting identical.
Date
| Format | Example | Description |
|---|---|---|
| YYYY-MM-DD | 2026-05-28 | Calendar date |
| YYYY-MM | 2026-05 | Year and month |
| YYYY | 2026 | Year only |
| YYYY-DDD | 2026-148 | Ordinal date (148th day of 2026) |
| YYYY-Www | 2026-W22 | Week date (22nd week of 2026) |
| YYYY-Www-D | 2026-W22-4 | Week date with day (Thursday of week 22) |
The hyphens are mandatory in the extended format (shown above). A compact format without hyphens — 20260528 — is also valid but less readable.
Time
| Format | Example | Description |
|---|---|---|
| hh:mm:ss | 14:30:00 | Local time |
| hh:mm:ssZ | 14:30:00Z | UTC (Zulu) time |
| hh:mm:ss+05:30 | 14:30:00+05:30 | UTC offset +5:30 |
| hh:mm | 14:30 | Hours and minutes only |
| hhmmss | 143000 | Compact format |
The Z suffix stands for "Zulu time" (UTC+0). Any other offset is written as ±hh:mm (or ±hhmm in compact form).
Combined Date and Time
The date and time are joined by the letter T:
2026-05-28T14:30:00Z
2026-05-28T14:30:00+02:00
2026-05-28T14:30:00.123Z (with milliseconds)
2026-05-28T14:30:00.123456Z (with microseconds)
The fractional seconds can have any number of decimal places, though most implementations standardize on 3 (milliseconds) or 6 (microseconds).
Timezone Handling
The most common source of confusion in ISO 8601 is timezone interpretation:
- Z suffix: The timestamp is in UTC. No conversion needed.
- Offset present: The timestamp is in the specified offset. Convert to UTC by subtracting the offset.
- No offset or Z: The timestamp is "local" time with no timezone information. This is ambiguous — local to whom?
Avoid offsetless timestamps in APIs and databases. Always include Z or an explicit offset.
Timezone conversion example
2026-05-28T14:30:00+02:00 (Berlin, summer)
→ Subtract offset: 14:30 - 02:00 = 12:30
→ UTC equivalent: 2026-05-28T12:30:00Z
Duration Format
ISO 8601 also defines a duration format using the P prefix:
| Duration | Meaning |
|---|---|
| P1Y2M3D | 1 year, 2 months, 3 days |
| PT12H30M | 12 hours, 30 minutes |
| P1Y2M3DT12H30M15S | Combined date and time duration |
| P1W | 1 week |
The T separates date components from time components. Note that P1M is one month (not one minute), while PT1M is one minute.
Common Pitfalls
Parsing inconsistencies
Not all ISO 8601 parsers handle all variations. JavaScript's Date.parse() and new Date() accept many formats but behave inconsistently across engines:
// These work in most engines:
new Date('2026-05-28T14:30:00Z') // OK — UTC
new Date('2026-05-28T14:30:00+02:00') // OK — with offset
// This is treated as LOCAL time in some engines, UTC in others:
new Date('2026-05-28T14:30:00') // Dangerous — no offset
// Date-only strings are treated as UTC:
new Date('2026-05-28') // Midnight UTC, not local
The safest approach: always serialize with Z or an explicit offset, and always use a dedicated date library (date-fns, Luxon, Day.js) for parsing.
Leap seconds
ISO 8601 allows the second value 60 to represent a positive leap second: 23:59:60Z. Most Unix systems smooth leap seconds across the day rather than exposing them, so timestamps with 60 seconds are rarely generated but should be handled gracefully by parsers.
Week date edge cases
Week dates follow ISO week numbering, where weeks start on Monday and the first week of the year contains the first Thursday. This means December 29 may belong to the first week of the next year, and January 1–3 may belong to the last week of the previous year.
ISO 8601 in Practice
| Context | Recommended Format | Example |
|---|---|---|
| REST API responses | ISO 8601 with Z | 2026-05-28T14:30:00Z |
| Database columns (PostgreSQL) | TIMESTAMPTZ stores UTC | 2026-05-28 14:30:00+00 |
| Log files | ISO 8601 with milliseconds | 2026-05-28T14:30:00.123Z |
| File naming | Compact, no colons | 20260528T143000Z |
| HTTP headers (If-Modified-Since) | IMF fixdate (RFC 7231) | Thu, 28 May 2026 14:30:00 GMT |
Key Takeaways
- ISO 8601 orders components from most to least significant, making string sort match chronological sort.
- Always include a timezone indicator (
Zor offset) — offsetless timestamps are ambiguous. - Use
Pfor durations andTto separate date from time components within a duration. - Avoid relying on JavaScript's native
Dateparser for ISO 8601; use a dedicated library. - Compact formats without delimiters are valid but reduce readability.
Try It Yourself
Need to convert between ISO 8601 formats and Unix timestamps? The Timestamp Converter handles both directions with support for UTC offsets and fractional seconds.