What does an ISO 8601 date look like?

ISO 8601 Date Format Explained

· Open the Date Formatter

An ISO 8601 date looks like 2026-09-26: four-digit year, two-digit month, two-digit day, largest unit first, separated by hyphens. A full timestamp adds a T, the time and an offset from UTC: 2026-09-26T14:05:00+05:30, or 2026-09-26T08:35:00Z where Z means UTC itself. That is the form almost everyone means by "ISO format", and it is the one to use for APIs, logs and file names. The standard itself is much larger. It also defines week dates, ordinal dates, a compact "basic" format without separators, reduced precision, decimal fractions, durations and intervals, and most of those variants are not accepted by most parsers.

Why the format works

Three design decisions make ISO 8601 the right default for machine-readable dates:

  • Largest unit first. 2026-09-26 cannot be misread as 9 February or 26 September depending on the reader's country, which 09/02/2026 can.
  • Fixed width, zero padded. Strings sort lexicographically in chronological order, provided they share the same offset. That is why 2026-09-26_backup.sql beats 26-9-2026_backup.sql as a file name.
  • Explicit offset. A timestamp with Z or +05:30 identifies one instant. Without it, the reader has to guess the zone.

Anatomy of a timestamp

Text
2026-09-26T14:05:00.123+05:30
│    │  │ ││  │  │ │   └───── UTC offset: +hh:mm, or Z for UTC
│    │  │ ││  │  │ └───────── decimal fraction of the second (. or ,)
│    │  │ ││  │  └─────────── second, 00–59 (60 during a leap second)
│    │  │ ││  └────────────── minute, 00–59
│    │  │ │└───────────────── hour, 00–23
│    │  │ └────────────────── T separates date from time
│    │  └──────────────────── day, 01–31
│    └─────────────────────── month, 01–12
└──────────────────────────── year, four digits (0000–9999)

Enter this timestamp into the Date Formatter and it will render it in any pattern and any zone:

ISO 8601 with an offsetOpen in Date Formatter
2026-09-26T14:05:00+05:30

With the default pattern yyyy-MM-dd'T'HH:mm:ssxxx, the output depends on the zone you choose, which is the point: the instant is fixed and only its representation changes.

Zone Output
Asia/Kolkata 2026-09-26T14:05:00+05:30
UTC 2026-09-26T08:35:00+00:00
America/New_York 2026-09-26T04:35:00-04:00

All three strings denote the same moment. Note that +00:00 and Z are equivalent; many serialisers emit Z, and the Date Formatter's pattern token xxx emits +00:00. Use XXX if you want Z.

Every variant in one table

Variant Extended format Basic format RFC 3339 Notes
Calendar date 2026-09-26 20260926 Yes (extended only) The common case
Reduced precision 2026-09, 2026 2026 No 202609 is not allowed: it would look like YYMMDD
Week date 2026-W39-6 2026W396 No ISO week-numbering year, week 01–53, weekday 1 (Monday) to 7
Ordinal date 2026-269 2026269 No Day of year, 001–366
Time 14:05:00, 14:05 140500, 1405 Seconds required
Decimal fraction 14:05:00.5, 14:05:00,5 140500,5 Dot only ISO historically preferred the comma; fractions apply to the smallest unit present, so 14:05,5 is 14:05:30
UTC 14:05:00Z 140500Z Yes (Z or z)
Offset +05:30, +05 +0530 ±hh:mm only
Date and time 2026-09-26T14:05:00+05:30 20260926T140500+0530 Yes RFC 3339 also allows a space or lowercase t
Duration P1DT2H30M15S same No (appendix only)
Interval 2026-09-26T09:00Z/2026-09-26T17:30Z same No Also start/duration and duration/end
Repeating interval R5/2026-09-26T09:00Z/P1D same No Five daily repetitions

The same date written three ways: 2026-09-26 is Saturday of ISO week 39, and the 269th day of the year. The Date Formatter produces the week form with the pattern RRRR-'W'II-i (output 2026-W39-6) and the ordinal form with yyyy-DDD (output 2026-269).

Week dates and the week-numbering year

ISO weeks start on Monday, and week 01 is the week containing the year's first Thursday (equivalently, the week containing 4 January). So the first days of January can belong to the last week of the previous year, and the last days of December to week 01 of the next. That "week-numbering year" is a separate field from the calendar year, and confusing the two is the cause of the YYYY formatting bug covered in date format patterns. Years with 53 ISO weeks are those that start on a Thursday, or leap years that start on a Wednesday; 2026 is one of them.

Durations

A duration is written P, then date components, then T, then time components:

Text
P1Y2M10DT2H30M15S   1 year, 2 months, 10 days, 2 hours, 30 minutes, 15 seconds
P2W                 2 weeks
PT36H               36 hours
P1M                 1 month
PT1M                1 minute

The T is what distinguishes months from minutes, so P1M and PT1M differ by a factor of about 43,800. Only the smallest component may carry a fraction (PT0.5S, P1.5D). Try one in the Duration Formatter:

ISO 8601 durationOpen in Duration Formatter
P1DT2H30M15S

It reads 1 day, 2 hours, 30 minutes, 15 seconds and totals 95,415 seconds. Two warnings apply to every duration library:

  • Years and months have no fixed length. P1M added to 31 January gives a different number of days than added to 1 February. Converting to seconds requires an average (the Duration Formatter uses 365.2425 days per year and 30.44 days per month, and says so).
  • Days are not always 24 hours. Across a daylight-saving transition, P1D and PT24H land on different wall-clock times. Java models this split explicitly: Period holds years, months and days; Duration holds exact seconds, and Duration.parse("P1DT2H30M15S") prints back as PT26H30M15S, while Duration.parse("P1M") throws.

ISO 8601 vs RFC 3339

RFC 3339 is a profile of ISO 8601 for internet protocols. It picks one unambiguous subset and adds two small extensions. JSON Schema's date-time format, most API style guides and many log formats reference RFC 3339, not ISO 8601.

ISO 8601 RFC 3339
Separator between date and time T (omission allowed by agreement in older editions) T, t, or a space "for readability"
Seconds Optional Required
Offset Optional (a time without one is local time) Required
Offset forms Z, ±hh:mm, ±hhmm, ±hh Z or ±hh:mm only
-00:00 Not given a distinct meaning Means "time is in UTC, local offset unknown"
Basic format, week and ordinal dates Yes No
Leap second :60 Yes Yes

The practical intersection, YYYY-MM-DDTHH:MM:SS[.fff](Z|±HH:MM), is valid under both. Emit exactly that and you will not need to know which one a consumer implements.

How languages parse it

Input JavaScript Date Python 3.11+ fromisoformat Java java.time
2026-09-26 Midnight UTC Naive midnight LocalDate.parse
2026-09-26T00:00 Midnight local Naive midnight LocalDateTime.parse
2026-09-26T14:05:00Z Parsed Parsed (from 3.11; earlier versions reject Z) Instant.parse
2026-09-26T14:05:00+05:30 Parsed Parsed OffsetDateTime.parse; Instant.parse since Java 12
20260926T140500+0530 Invalid Date Parsed Needs a custom pattern (BASIC_ISO_DATE covers the date part only)
2026-W39-6 Invalid Date Parsed DateTimeFormatter.ISO_WEEK_DATE
2026-269 Invalid Date Rejected DateTimeFormatter.ISO_ORDINAL_DATE
Comma fraction 2026-09-26T14:05:00,5+05:30 Invalid Date Parsed Needs a custom pattern

The first two rows are the most common JavaScript date bug. The ECMAScript specification says a date-only ISO string is UTC but a date-time without an offset is local time. In India, new Date("2026-09-26") is 05:30 local time on the 26th, while new Date("2026-09-26T00:00") is 18:30 UTC on the 25th. In the Americas, the date-only form displays as the previous day. If you mean a calendar date with no time, keep it as a string or a date-only type; if you mean an instant, include the offset.

Mistakes that produce valid-looking but wrong strings

  • A literal Z on a local time. Patterns such as yyyy-MM-dd'T'HH:mm:ss'Z' print the letter Z whatever the value's zone is. If the value is local time, the string claims to be UTC and is off by the local offset. Use an offset token (XXX in date-fns and Java, %z in Python) or convert to UTC first. JavaScript's toISOString() is safe because it always converts to UTC.
  • Missing zero padding. 2026-9-26 is not ISO 8601, will not sort correctly, and is rejected by strict parsers.
  • An offset is not a time zone. +05:30 records the offset at one instant. It says nothing about daylight-saving rules, so it cannot tell you the offset of the same wall-clock time next month. For future events in local time (a meeting at 09:00 in New York every Monday), store the local time and the IANA zone name, and compute the offset when needed.
  • Two-digit years and implied centuries. ISO 8601 no longer allows two-digit years in its general forms; always write four digits.

Rules for using ISO 8601 in systems

  1. Serialise instants as RFC 3339 with an explicit offset, preferably Z for stored and logged values.
  2. Use calendar dates (2026-09-26) for date-only values such as birthdays and due dates, and never attach a time or zone to them.
  3. Include fractional seconds only when you need them, and document the precision; JavaScript keeps milliseconds, Python microseconds, Java and PostgreSQL up to nanoseconds and microseconds respectively.
  4. Do not assume other variants will parse. Week dates, ordinal dates, basic format and comma fractions are valid ISO 8601 and are rejected by common parsers.
  5. For stored numeric instants, see Unix timestamps; to convert an ISO string to epoch seconds, use the Unix Timestamp Converter.

Tools used in this guide