ISO 8601 date / datetime regex
ISO 8601 dates and optional datetimes with timezone, the format every modern JSON API speaks.
^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:\d{2})?)?$/What it matches
ISO 8601 is the date format that JSON APIs and CSV exports default to. The basic shape is `YYYY-MM-DD`; for datetimes you append `T`, then a time, then an optional timezone (`Z` for UTC or `±HH:MM` for offset). This pattern matches the date alone, the date + time, the date + time with seconds, and the date + time with fractional seconds and a timezone.
Examples
Matches
2026-05-15Date-only.
2026-05-15T13:45:00ZDate + time + UTC.
2026-05-15T13:45:00.123+05:30Date + time + milliseconds + India Standard Time offset.
2026-05-15T13:45Date + time without seconds — valid ISO 8601.
Does not match
15/05/2026DD/MM/YYYY format.
May 15 2026Localized English format.
2026-5-15Single-digit month — ISO requires zero-padding.
2026-05-15 13:45:00Space separator between date and time — ISO requires `T` (some flavors accept space, but the strict pattern doesn't).
Edge cases & gotchas
- Doesn't validate that the date is real — `2026-02-30` matches even though February has 28 days. Always parse with `Date.parse()` or `Date.fromISOString()` after the regex check.
- Accepts year 0000 and 9999 — fine for the format, weird for your application. Add `(?!0000)` after `^` to forbid year zero.
- Doesn't accept the basic ISO format without separators (`20260515T134500Z`). Add an alternation if you need both extended and basic.
- Doesn't validate timezone offset bounds — accepts `+25:00` which is invalid. Tighten with `(?:[01]\d|2[0-3]):[0-5]\d` for the offset.
In your language
// JavaScript
const re = /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:\d{2})?)?$/;
const match = "input".match(re);All 13 languages (including Bash, Perl, Kotlin, Swift) available in the full toolkit Export tab.
Notes for production
- JavaScript: `new Date('2026-05-15').toISOString()` round-trips ISO 8601 cleanly. Use that for normalization.
- Postgres `timestamptz` columns accept ISO 8601 directly — no string parsing needed in queries.
Frequently asked
Does this accept 'today' or 'yesterday'?
No — those are natural-language dates, not ISO 8601. You need an NLP parser like Chrono.js or your AI tool of choice.
Why doesn't `2026-02-30` get rejected?
Regex can't do calendar math. The pattern enforces shape only; you need a real parser to know February doesn't have 30 days. After the regex passes, run `new Date(s).toISOString() === s` to catch impossible dates.
What about week-numbered dates like `2026-W20-5`?
ISO 8601 supports them but they're uncommon. This pattern doesn't match them — add a separate alternation if you need to.