New blogMaking an AI Agent You Can Trust With Money

★ Dev formats · regex

Regex for ISO 8601 Date

Checks the calendar-date form of ISO 8601: a four-digit year, month 01–12 and day 01–31. It won't catch impossible dates like 2023-02-30; parse the date to check that.

  • Runs in your browser
  • No signup

Try the iso 8601 date pattern

Read it in plain English (best-effort)

  • ^start of a line
  • \da digit (0–9)
  • {4}exactly 4 of the previous
  • -the character '-'
  • (?:start a group (not captured)
  • 0the character '0'
  • [1-9]one character from: 1–9
  • |or
  • 1the character '1'
  • [0-2]one character from: 0–2
  • )end of group
  • -the character '-'
  • (?:start a group (not captured)
  • 0the character '0'
  • [1-9]one character from: 1–9
  • |or
  • [12]one character from: '1', '2'
  • \da digit (0–9)
  • |or
  • 3the character '3'
  • [01]one character from: '0', '1'
  • )end of group
  • $end of a line

One sample per line works well with the m flag on anchored patterns.

Waiting for a pattern
01

The pattern, piece by piece

/^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])$/
Pattern explanation
PartWhat it does
^\d{4}four-digit year
-(?:0[1-9]|1[0-2])month 01–12
-(?:0[1-9]|[12]\d|3[01])day 01–31
$nothing after the date
02

What it accepts and rejects

Every sample below is checked automatically in JavaScript and Python. The tester above is preloaded with all of them, one per line.

Should match
Should match
2026-11-08✓
1999-12-31✓
2024-02-29✓
2000-01-01✓
2026-07-15✓
2010-10-10✓
Should not match
Should not match
2026-13-01✗
2026-00-10✗
2026-02-32✗
26-11-08✗
2026/11/08✗
2026-1-8✗
2026-11-08T10:00:00Z✗
03

Copy it into your code

RE2-safeNo lookarounds or backreferences, so the same pattern works in Go's RE2 engine and in Rust's regex crate.

const isoDateRe = /^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])$/;

export function isValidIsoDate(value) {
  return isoDateRe.test(value.trim());
}
04

When not to use regex for this

Leap years and month lengths are calendar logic. After the format check, parse with your date library and confirm it round-trips to the same string; that rejects 2023-02-30 and 2026-04-31.

05

Questions engineers actually ask

Why does 2023-02-30 pass?
Regex checks shape, not the calendar. Parse the date and compare the result to catch impossible days.
Does it match timestamps like 2026-11-08T10:00:00Z?
No, it's date-only. Extend it with a time part, or parse full timestamps with your date library.
What is catastrophic backtracking?
Some patterns, usually nested quantifiers like (a+)+, make a backtracking engine try an exponential number of paths on input that almost matches. The tester stops any run after 300ms, so a bad pattern can't freeze your tab. In production, that same pattern can take down a server (a ReDoS attack).
06

More dev formats patterns

07

More from the workbench

Fine print

Tools: on the house.
Engineer: by the hour.

The regex was free. Code that doesn't need one is the upgrade: typed schemas, validated once at the edge, trusted everywhere after.

I'm Himanshu, an AI and full-stack engineer. I build MVPs, AI agents and the growth plumbing around them for early-stage startups.