ISO 8601 Date Format Explained

A practical breakdown of the ISO 8601 date and time standard — what it is, why it matters, the different format variants, and how to use them correctly in APIs, databases, and everyday work.


What Is ISO 8601?

ISO 8601 is an international standard published by the International Organization for Standardization (ISO) that defines how to represent dates and times as text strings. Its most recognizable form looks like this: 2024-06-29T14:30:00Z.

The standard was first published in 1988 and most recently updated in 2019. Its purpose is simple: eliminate the ambiguity that arises when different countries, systems, and organizations use different date formats. When you see 06/07/2024, you can't know whether it means June 7th or July 6th without knowing the author's locale. ISO 8601 removes that problem entirely by mandating a single, unambiguous format: year first, then month, then day, with dashes as separators.

Today, ISO 8601 is the de facto standard for date exchange in web APIs, JSON payloads, log files, databases, and international business. If you've ever worked with a REST API, you've almost certainly seen ISO 8601 dates.

The Format, Piece by Piece

The full ISO 8601 datetime string has this structure:

YYYY-MM-DDTHH:mm:ss.sssZ
│    │  │  │ │  │  │   └─ timezone designator
│    │  │  │ │  │  └───── fractional seconds
│    │  │  │ │  └──────── seconds (00–59)
│    │  │  │ └─────────── minutes (00–59)
│    │  │  └───────────── hours (00–23)
│    │  │  └───────────── T separator (literal "T")
│    │  └──────────────── day (01–31)
│    └─────────────────── month (01–12)
└──────────────────────── year (four digits)

Each piece has specific rules:

Date portion — Always YYYY-MM-DD with four-digit years and zero-padded months and days. 2024-06-29 is valid. 2024-6-29 is not strictly compliant (though many parsers accept it).

The T separator — The literal letter T separates the date from the time. Some systems accept a space instead of T (e.g., 2024-06-29 14:30:00), and RFC 3339 — a profile of ISO 8601 used widely on the web — explicitly allows this. But the canonical ISO 8601 form uses T.

Time portion — 24-hour clock, zero-padded. 14:30:00 is 2:30 PM. 02:30:00 is 2:30 AM. There is no AM/PM in ISO 8601.

Fractional seconds — Optional, appended after the seconds with a decimal point. 14:30:00.000 is zero milliseconds. 14:30:00.123456 is valid too — the standard doesn't limit the number of decimal places.

Timezone designator — This is where things get interesting, and it's covered in detail below.

Timezone Designators: Z, Offsets, and Omission

ISO 8601 supports three ways to indicate timezone:

Z (Zulu Time / UTC)

The letter Z at the end means UTC — Coordinated Universal Time. It's sometimes called "Zulu time" in aviation and military contexts (Z is the NATO phonetic alphabet code for the UTC timezone). Example: 2024-06-29T14:30:00Z means 2:30 PM UTC.

UTC Offset

Instead of Z, you can specify an offset from UTC as +HH:mm or -HH:mm. Examples:

2024-06-29T14:30:00+00:00 — same as Z (UTC)
2024-06-29T10:30:00-04:00 — 10:30 AM in UTC-4 (Eastern Daylight Time), which is the same instant as 14:30 UTC
2024-06-29T23:30:00+09:00 — 11:30 PM in UTC+9 (Japan Standard Time), same instant again

All three of these represent the exact same moment in time, just expressed in different local times. The offset tells you how far the local time is from UTC.

No Timezone (Local Time)

If there's no Z and no offset, the datetime is considered local time — the timezone is unspecified. 2024-06-29T14:30:00 (no Z, no offset) means "2:30 PM in whatever timezone the reader assumes." This is ambiguous and should generally be avoided in data exchange. However, it's common in contexts where the timezone is implied, such as timestamps in a local database or a user-facing form where the timezone is known from context.

Common Variants You'll Encounter

VariantExampleWhere You'll See It
Date only2024-06-29SQL DATE columns, calendar entries, HTML date inputs
Date + time (UTC)2024-06-29T14:30:00ZREST APIs, JSON, log files, JavaScript toISOString()
With milliseconds2024-06-29T14:30:00.000ZJavaScript, Java, high-precision logging
With offset2024-06-29T14:30:00+05:30Timezone-aware APIs, international systems
Space separator2024-06-29 14:30:00SQL DATETIME, Python str(), database exports
No seconds2024-06-29T14:30ZMeeting times, calendar events
Week date2024-W26-6ISO week numbering (finance, logistics)
Ordinal date2024-181Day-of-year format (astronomy, military)

The first four variants are by far the most common in software development. Week dates and ordinal dates exist in the standard but are rarely seen outside specialized industries.

ISO 8601 vs. RFC 3339

You'll often see ISO 8601 and RFC 3339 mentioned together. RFC 3339 is an Internet Engineering Task Force (IETF) standard that defines a profile of ISO 8601 — a subset of the full standard tailored for internet protocols. The key differences:

RFC 3339 requires a timezone designator (either Z or an offset). ISO 8601 allows local time without a timezone. RFC 3339 allows a space instead of T as the separator. ISO 8601 technically requires T. RFC 3339 doesn't support week dates or ordinal dates.

In practice, most web APIs and JSON formats follow RFC 3339, and most parsers that accept "ISO 8601" also accept RFC 3339 (and vice versa). If you're building an API, targeting RFC 3339 compliance is the pragmatic choice — it's more specific and eliminates ambiguity.

Why Year-Month-Day Order?

The year-first ordering isn't arbitrary. It has two practical advantages:

Lexicographic sorting works. If you sort ISO 8601 date strings alphabetically, they come out in chronological order. 2024-01-15 sorts before 2024-06-29 which sorts before 2025-01-01. This doesn't work with US (06/29/2024) or European (29.06.2024) formats — alphabetical sorting produces nonsensical results with day-first or month-first orderings.

It matches descending significance. Year is the most significant component, then month, then day, then hour, and so on — just like how we write numbers with the most significant digit first. This makes the format internally consistent and easy to parse visually.

Working with ISO 8601 in Code

JavaScript

// Generate ISO 8601 string (always UTC with Z)
new Date().toISOString()
// → "2024-06-29T14:30:00.000Z"

// Parse ISO 8601
new Date("2024-06-29T14:30:00Z")
// → valid Date object

// Parse with offset
new Date("2024-06-29T14:30:00+05:30")
// → Date object adjusted to UTC internally

Python

from datetime import datetime, timezone

# Generate ISO 8601
datetime.now(timezone.utc).isoformat()
# → "2024-06-29T14:30:00+00:00"

# Parse ISO 8601 (Python 3.11+)
datetime.fromisoformat("2024-06-29T14:30:00+00:00")

# Parse with Z suffix (Python 3.11+)
datetime.fromisoformat("2024-06-29T14:30:00Z")

Note: Before Python 3.11, fromisoformat() did not accept the Z suffix. You needed to replace Z with +00:00 first, or use dateutil.parser.

SQL

-- PostgreSQL handles ISO 8601 natively
SELECT '2024-06-29T14:30:00Z'::timestamptz;

-- MySQL also accepts it
SELECT CAST('2024-06-29T14:30:00' AS DATETIME);

-- For timezone-aware storage, use TIMESTAMP WITH TIME ZONE (PostgreSQL)
-- or convert explicitly in MySQL

Common Mistakes

Assuming local time is UTC. The string 2024-06-29T14:30:00 (no Z, no offset) is local time, not UTC. If you treat it as UTC when the original system meant Eastern Time, you'll be off by 4–5 hours.

Dropping the timezone on storage. Storing 2024-06-29T14:30:00 in a database column without timezone info, then later trying to reconstruct the timezone from context, is a frequent source of bugs. Always store timezone-aware timestamps when the timezone matters.

Using two-digit years. ISO 8601 requires four-digit years. 24-06-29 is not valid ISO 8601.

Mixing separators. 2024/06/29 with slashes is not ISO 8601. The standard uses dashes for dates and colons for times.

Related Guides

ISO 8601 dates can be converted to and from Unix timestamps — see What Is a Unix Timestamp? for the relationship between the two. For a side-by-side comparison of ISO 8601 with every other common date format, see the Date Format Cheat Sheet. To understand timezone abbreviations like EST, UTC, and JST, see the Timezone Abbreviations Reference. For the older email date format that ISO 8601 has largely replaced, see RFC 2822 Explained. For the surprising pitfalls of parsing ISO 8601 strings in JavaScript specifically, see JavaScript Date Parsing Pitfalls.

Try It Yourself

Convert any date or timestamp instantly — free, no sign-up required.

Open the Converter