ISO-8601 is the international standard for representing dates and times as text. A correctly built ISO-8601 string sorts chronologically as plain text, is unambiguous across locales, and is accepted by virtually every programming language and database. This tool lets you assemble one field-by-field and validates each part so you never emit an impossible date.
How it works
The builder zero-pads each component to the right width and joins them in the canonical order:
YYYY-MM-DDThh:mm:ss±hh:mm
Before producing output it validates the calendar date. The number of days in a month depends on the month and, for February, on whether the year is a leap year. A year is a leap year if it is divisible by 4, except century years which must also be divisible by 400:
const leap = (y % 4 === 0 && y % 100 !== 0) || y % 400 === 0;
const daysInMonth = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
The time fields are checked against their ranges (hour 0–23, minute and second 0–59), and the timezone is rendered either as Z for UTC or as a signed ±hh:mm offset. As a final check, the assembled string is passed to Date.parse to confirm the runtime accepts it.
Example
Year 2026, month 6, day 6, 14:30:00 at offset +01:00 produces:
2026-06-06T14:30:00+01:00
Switching the offset to Z (UTC) and the hour to 13 gives the same instant:
2026-06-06T13:30:00Z
Tips and notes
- Always include the timezone designator; a date-time without one is ambiguous about which clock it refers to.
- The
Tseparator is required by strict ISO-8601; a space is tolerated by some parsers but is not portable. - For storage, UTC (Z) is usually the safest choice — convert to a local offset only for display.