# Regex for ISO 8601 Date-Times

> ISO 8601 / RFC 3339 datetime regex for timestamps like 2026-10-15T09:30:00Z and offsets like +02:00, with fractional seconds. Explained token by token.

```
/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/
```

This pattern matches full ISO 8601 timestamps in the RFC 3339 profile that APIs and JSON use: a date, a T, a time with seconds, optional fractional seconds, and a mandatory time zone — Z for UTC or an offset like +02:00. It checks the shape; impossible values like month 13 still need a date parser.

## Token by token

| Token | Meaning |
|---|---|
| `^\d{4}-\d{2}-\d{2}` | the date: YYYY-MM-DD |
| `T` | the literal separator between date and time |
| `\d{2}:\d{2}:\d{2}` | the time: hh:mm:ss |
| `(?:\.\d+)?` | optional fractional seconds (.123 or .123456) |
| `(?:Z\|[+-]\d{2}:\d{2})` | the time zone: Z, or an offset such as +02:00 |
| `$` | end of string |

## Examples

- ✓ matches: `2026-10-15T09:30:00Z`
- ✓ matches: `2026-10-15T09:30:00.123Z`
- ✓ matches: `2026-10-15T09:30:00+02:00`
- ✓ matches: `2026-10-15T09:30:00.5-05:00`
- ✗ does not match: `2026-10-15`
- ✗ does not match: `2026-10-15T09:30:00`
- ✗ does not match: `2026-10-15 09:30:00Z`
- ✗ does not match: `2026-10-15T09:30Z`

## Variations

- `^\d{4}-\d{2}-\d{2}[Tt ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:[Zz]|[+-]\d{2}:\d{2})$` — RFC 3339 also permits a space instead of T, and lowercase t and z
- `^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?(?:Z|[+-]\d{2}:?\d{2})?$` — looser ISO 8601: seconds and zone optional, offsets with or without a colon

## Language notes

- JavaScript's Date.parse accepts these strings but treats a date-time with no zone as local time — one more reason to require Z or an offset.

## FAQ

### Does this reject invalid dates like 2026-02-30?

No — it checks the format only. Parse the value (new Date(value) in JavaScript, datetime.fromisoformat in Python) and check the result to catch impossible dates.

### Why require a time zone?

A timestamp without one is ambiguous — 09:30 where? Requiring Z or an offset makes every value point at one exact instant.

## Related patterns

- [Regex for Dates in YYYY-MM-DD Format](https://www.devkult.com/regex/date-yyyy-mm-dd.md)
- [Regex for 24-Hour Time (HH:MM)](https://www.devkult.com/regex/time-24h.md)
- [Regex for UUID Validation](https://www.devkult.com/regex/uuid.md)

Open the interactive page: https://www.devkult.com/regex/iso-8601-datetime