1001Ferramentas
πŸ“…Validators

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 trailing Z is "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:MM or -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 as 2024-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 TIMESTAMPTZ columns 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