ISO 8601 Date Validator
Verify whether a string is a valid ISO 8601 date/time (with timezone) and show the detected components.
ISO 8601: the international standard for representing dates and times
ISO 8601 is the international standard published by the ISO that defines how dates, times, time intervals and durations are written as strings. Its biggest contribution is a single, unambiguous, sortable text representation: YYYY-MM-DD, where the most significant component (year) comes first. The format eliminates the eternal US-vs-UK confusion over 03/04/2024 (March 4 or April 3?).
The W3C profile is a subset adopted by XML, JSON Schema, RFC 3339 and almost every modern API. This validator checks the most common production variants β date-only, date-time, fractional seconds, and timezone offsets.
The four canonical forms
From simplest to richest:
YYYY-MM-DDβ calendar date, e.g.2024-03-15.YYYY-MM-DDTHH:MM:SSβ local date-time, no timezone:2024-03-15T10:30:00.YYYY-MM-DDTHH:MM:SS+HH:MMβ date-time with offset:2024-03-15T10:30:00-03:00(BRT).YYYY-MM-DDTHH:MM:SS.sssZβ UTC with milliseconds:2024-03-15T13:30:00.000Z. The trailingZis "Zulu", short for+00:00.
Other variants exist (ordinal dates 2024-075, week dates 2024-W11-5, durations P1Y2M10DT2H30M) but they are rare in APIs.
Parsing in JavaScript: native vs library
JavaScript's new Date(str) understands ISO 8601 but is permissive: it accepts non-ISO inputs ("2024/03/15") with implementation-defined behavior. Date.parse() returns NaN on unrecognised strings, which is a slightly safer check.
// strict ISO check
const isISO = !isNaN(Date.parse(str)) &&
/^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2}))?$/.test(str)
For production code, prefer a library. date-fns ships parseISO, formatISO and isValid. Day.js is a 2 KB drop-in replacement for Moment.js. Luxon excels at timezone handling via the IANA database. The new Temporal API (Stage 3 in TC39) will replace Date with a richer model β Temporal.PlainDate, Temporal.ZonedDateTime, Temporal.Duration.
Edge cases: leap years, month length and DST
A truly strict validator must reject impossible dates:
- Leap year β February 29 only exists when
year % 4 == 0 && (year % 100 != 0 || year % 400 == 0). So 2000 was a leap year, 1900 was not, 2024 is, 2100 will not be. - 31st in 30-day months β April, June, September, November cap at 30; February at 28 or 29.
- Daylight saving transitions β in countries that still observe DST, certain local times do not exist (clock jumps forward) or exist twice (clock falls back). ISO 8601 sidesteps this by recommending UTC or an explicit offset.
Brazil is special: the country abolished daylight saving in 2019, so the BRT offset is a fixed -03:00 year-round (Acre is -05:00).
Timezones: Z vs offset vs IANA
Three ways to anchor a date-time in time:
Zβ UTC, equivalent to+00:00. The most portable choice for APIs and databases.+HH:MMor-HH:MMβ fixed numeric offset. Captures the instant but loses the rule (DST, political changes).- IANA timezone (
America/Sao_Paulo) β not part of ISO 8601 itself, but Temporal and many libraries append it as2024-03-15T10:30:00-03:00[America/Sao_Paulo].
Rule of thumb: store UTC, display local. Postgres TIMESTAMPTZ follows that pattern, MySQL DATETIME does not (it stores naive local time). Always validate inputs against the same parser you use server-side to avoid silent timezone drift.
Library comparison: Moment, Day.js, date-fns, Luxon
- Moment.js β historically dominant, officially in maintenance mode since 2020. Avoid for new projects.
- Day.js β 2 KB, Moment-compatible API, immutable, plugin-based.
- date-fns β functional, tree-shakeable:
import {format, parseISO} from 'date-fns'. - Luxon β by the Moment team, best timezone support via IANA.
- js-joda β port of Java's java.time, immutable and very strict.
Use cases for an ISO 8601 validator
- API request validation with Zod (
z.string().datetime()) or Joi. - HTML form input using
<input type="date">β browsers emit ISO date-only strings. - PostgreSQL
TIMESTAMPTZcolumns and JSON fields. - Front-end inspection of API payloads before sending to
new Date().
FAQ
Is a date-only string like 2024-03-15 valid ISO 8601?
Yes. The standard explicitly allows date-only and time-only forms. JSON Schema's format: "date" targets exactly this.
Is the timezone mandatory?
For date-only strings, no β there is no time, so no timezone is meaningful. For date-time strings, the standard allows omitting it, but every modern API requires either Z or an explicit offset to avoid ambiguity.
Will the year 2038 bug affect ISO 8601?
Yes for systems that store the timestamp as signed 32-bit Unix epoch: that integer overflows in January 2038. The ISO 8601 textual format itself is unaffected β the issue is the underlying storage. Migrate to 64-bit time_t or store strings.
What is the difference between Z and +00:00?
Semantically nothing β both denote UTC. Z is shorter and recommended by RFC 3339. Some old parsers reject Z; some reject +00:00. Pick one and stay consistent.
Should I trust new Date(str) in JavaScript?
For strict ISO 8601 input, mostly yes β but the browser may accept extra garbage. For untrusted input, validate with a regex or a library before constructing the Date. The upcoming Temporal API fixes most of these papercuts.
Related Tools
CPF Validator
Validate Brazilian CPF numbers instantly using the official algorithm. Useful for testing document validation in applications. No data sent to servers.
Batch CPF Validator
Validate a list of CPFs (one per line) and see which are valid and which are not. No data sent to servers.
Batch CNPJ Validator
Validate a list of CNPJs (one per line) with a summary of valid, invalid and total. No data sent to servers.