X Xerobit

ISO 8601 Date Format — The Standard for Dates in APIs and Databases

ISO 8601 is the international standard for representing dates and times. Learn the format, timezone designators, durations, intervals, and why ISO 8601 is mandatory for APIs,...

Mian Ali Khalid · · 4 min read
Use the tool
Timestamp Converter
Convert Unix timestamps, epoch seconds/milliseconds, and ISO 8601 dates.
Open Timestamp Converter →

ISO 8601 is the international standard (ISO 8601:2019) for representing dates and times. It eliminates ambiguity in data exchange — unlike “01/02/03” (is that January 2, 2003? February 1? Or February 3, 2001?).

Use the Timestamp Converter to convert between ISO 8601 and Unix timestamps.

Basic ISO 8601 formats

Date only:
  2026-05-12                    YYYY-MM-DD (recommended)
  20260512                      YYYYMMDD (compact, less common)

Date and time:
  2026-05-12T14:30:00           Local time (no timezone — ambiguous, avoid)
  2026-05-12T14:30:00Z          UTC (Z = Zulu = UTC+00:00)
  2026-05-12T14:30:00+05:30     UTC+5:30 (India Standard Time)
  2026-05-12T14:30:00-04:00     UTC-4:00 (Eastern Daylight Time)

With milliseconds:
  2026-05-12T14:30:00.000Z      Milliseconds (3 digits)
  2026-05-12T14:30:00.000000Z   Microseconds (6 digits)

Always include a timezone offset when communicating between systems. 2026-05-12T14:30:00 with no offset is ambiguous.

RFC 3339 vs ISO 8601

RFC 3339 is a profile of ISO 8601 commonly referenced in internet standards:

FeatureISO 8601RFC 3339
Timezone designatorZ or ±HH:MMZ or ±HH:MM
T separatorOptional (can use space)Required
- and : separatorsOptionalRequired
ScopeInternational standardInternet protocol use

In practice: When APIs say “ISO 8601”, they usually mean RFC 3339 format: 2026-05-12T14:30:00Z. Use this format.

JavaScript: producing ISO 8601

const date = new Date('2026-05-12T14:30:00Z');

// Full ISO 8601 with milliseconds:
date.toISOString();           // "2026-05-12T14:30:00.000Z"

// Date only:
date.toISOString().split('T')[0];  // "2026-05-12"

// With timezone offset (not UTC):
// Use Intl.DateTimeFormat or date-fns-tz
import { formatISO } from 'date-fns';
formatISO(date);              // "2026-05-12T14:30:00Z"

Python: producing ISO 8601

from datetime import datetime, timezone

dt = datetime(2026, 5, 12, 14, 30, 0, tzinfo=timezone.utc)

# Standard ISO 8601:
dt.isoformat()             # "2026-05-12T14:30:00+00:00"

# With 'Z' suffix (more common in APIs):
dt.strftime('%Y-%m-%dT%H:%M:%SZ')  # "2026-05-12T14:30:00Z"

# Python 3.11+ accepts 'Z' in fromisoformat:
datetime.fromisoformat('2026-05-12T14:30:00Z')

# Earlier Python: replace 'Z' with '+00:00'
datetime.fromisoformat('2026-05-12T14:30:00Z'.replace('Z', '+00:00'))

ISO 8601 durations

Durations use the format P[n]Y[n]M[n]DT[n]H[n]M[n]S:

P = Period (required prefix)
Y = Years
M = Months (before T)
D = Days
T = Time separator (required when including time elements)
H = Hours
M = Minutes (after T)
S = Seconds

Examples:
P1Y        = 1 year
P3M        = 3 months
P7D        = 7 days
PT2H       = 2 hours
PT30M      = 30 minutes
P1Y2M3DT4H5M6S = 1 year, 2 months, 3 days, 4 hours, 5 minutes, 6 seconds

Used in APIs for cache TTLs, subscription intervals, and time-to-live values.

ISO 8601 intervals

Start/End:  2026-05-01T00:00:00Z/2026-05-31T23:59:59Z
Start/Duration:  2026-05-01T00:00:00Z/P1M  (1 month from start)
Duration/End:    P1M/2026-05-31T23:59:59Z  (1 month before end)

Used in calendar APIs, scheduling systems, and data range queries.

Why ISO 8601 for APIs

{
  "created_at": "2026-05-12T14:30:00Z",
  "updated_at": "2026-05-12T15:00:00.000Z",
  "expires_at": "2026-06-12T14:30:00Z",
  "duration": "PT1H30M"
}

Benefits:

  • Sortable lexicographically — ISO dates sort correctly as strings
  • Unambiguous — unlike MM/DD/YYYY vs DD/MM/YYYY
  • Machine-readable — parseable by every language’s standard library
  • Timezone explicit — no implicit assumptions about server timezone

Database storage

-- PostgreSQL:
-- Store as TIMESTAMPTZ (timestamp with timezone) — always UTC internally
CREATE TABLE events (
    id SERIAL PRIMARY KEY,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    event_date DATE NOT NULL  -- Date-only columns use DATE type
);

-- MySQL/MariaDB:
-- DATETIME stores without timezone; use TIMESTAMP for UTC auto-conversion
-- Or store as BIGINT Unix timestamp for portability

-- SQLite:
-- No native datetime type; store as ISO 8601 TEXT or Unix integer

Related posts

Related tool

Timestamp Converter

Convert Unix timestamps, epoch seconds/milliseconds, and ISO 8601 dates.

Written by Mian Ali Khalid. Part of the Dev Productivity pillar.