1001Ferramentas
📅Validadores

Validador de Data ISO 8601

Confere se uma string é uma data/hora ISO 8601 válida (incluindo timezone) e mostra os componentes detectados.

ISO 8601: o padrão internacional para representar datas e horários

ISO 8601 e o padrão internacional publicado pela ISO que define como datas, horários, intervalos e duracoes são escritos como string. Sua maior contribuicao e uma representação textual única, sem ambiguidade e ordenavel: YYYY-MM-DD, com o componente mais significativo (ano) primeiro. O formato elimina a eterna confusão EUA-vs-Reino Unido com 03/04/2024 (4 de marco ou 3 de abril?).

O perfil W3C e um subconjunto adotado por XML, JSON Schema, RFC 3339 e quase toda API moderna. Este validador checa as variantes mais comuns em produção — date-only, date-time, segundos fracionados e offsets de fuso.

As quatro formas canonicas

Da mais simples a mais rica:

  • YYYY-MM-DD — data de calendário, ex.: 2024-03-15.
  • YYYY-MM-DDTHH:MM:SS — data-hora local, sem fuso: 2024-03-15T10:30:00.
  • YYYY-MM-DDTHH:MM:SS+HH:MM — data-hora com offset: 2024-03-15T10:30:00-03:00 (BRT).
  • YYYY-MM-DDTHH:MM:SS.sssZ — UTC com milissegundos: 2024-03-15T13:30:00.000Z. O Z final e "Zulu", abreviacao de +00:00.

Existem outras variantes (datas ordinais 2024-075, semanas 2024-W11-5, duracoes P1Y2M10DT2H30M), mas são raras em APIs.

Parse em JavaScript: nativo vs biblioteca

O new Date(str) do JavaScript entende ISO 8601, mas e permissivo: aceita entradas não-ISO ("2024/03/15") com comportamento definido pela implementação. Date.parse() devolve NaN em strings desconhecidas, o que e um check levemente mais seguro.

// checagem ISO estrita
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)

Em código de produção, prefira biblioteca. date-fns traz parseISO, formatISO e isValid. Day.js e um substituto de 2 KB para o Moment.js. Luxon brilha em fuso horário via base IANA. A nova Temporal API (Stage 3 no TC39) vai substituir o Date por um modelo mais rico — Temporal.PlainDate, Temporal.ZonedDateTime, Temporal.Duration.

Casos limite: anos bissextos, comprimento de mês e horário de verão

Um validador realmente estrito precisa rejeitar datas impossiveis:

  • Ano bissexto — 29 de fevereiro so existe se ano % 4 == 0 && (ano % 100 != 0 || ano % 400 == 0). Por isso 2000 foi bissexto, 1900 não foi, 2024 e, e 2100 não sera.
  • Dia 31 em meses de 30 — abril, junho, setembro, novembro vão até 30; fevereiro até 28 ou 29.
  • Transicoes de horário de verão — em paises que ainda adotam DST, alguns horários locais não existem (relógio adianta) ou existem duas vezes (relógio atrasa). ISO 8601 contorna isso recomendando UTC ou offset explícito.

O Brasil tem um caso especial: o pais aboliu o horário de verão em 2019, então o offset BRT e fixo em -03:00 o ano inteiro (o Acre fica em -05:00).

Fusos horários: Z vs offset vs IANA

Três formas de ancorar uma data-hora no tempo:

  • Z — UTC, equivale a +00:00. A escolha mais portavel para APIs e bancos.
  • +HH:MM ou -HH:MM — offset numérico fixo. Captura o instante mas perde a regra (DST, mudanças politicas).
  • Fuso IANA (America/Sao_Paulo) — não faz parte do ISO 8601, mas o Temporal e muitas bibliotecas anexam como 2024-03-15T10:30:00-03:00[America/Sao_Paulo].

Regra pratica: guarde UTC, exiba local. O TIMESTAMPTZ do Postgres segue esse padrão; o DATETIME do MySQL não (guarda local naive). Sempre valide entrada com o mesmo parser usado no servidor para evitar deriva silenciosa de fuso.

Comparação de bibliotecas: Moment, Day.js, date-fns, Luxon

  • Moment.js — historicamente dominante, oficialmente em modo manutencao desde 2020. Evite em projetos novos.
  • Day.js — 2 KB, API compatível com Moment, imutavel, baseada em plugins.
  • date-fns — funcional, tree-shakeable: import {format, parseISO} from 'date-fns'.
  • Luxon — do mesmo time do Moment, melhor suporte a fuso via IANA.
  • js-joda — port do java.time, imutavel e bem estrito.

Usos tipicos de um validador ISO 8601

  • Validação de requisição de API com Zod (z.string().datetime()) ou Joi.
  • Input HTML <input type="date"> — os navegadores emitem strings ISO date-only.
  • Colunas TIMESTAMPTZ em PostgreSQL e campos JSON.
  • Inspecao no front antes de jogar em new Date().

FAQ

So a data como 2024-03-15 e valida em ISO 8601?

Sim. O padrão permite explicitamente formas date-only e time-only. O format: "date" do JSON Schema mira justamente isso.

O fuso horário e obrigatório?

Em strings date-only, não — não ha hora, então não ha fuso a representar. Em date-time, o padrão admite omitir, mas toda API moderna exige ou Z ou offset explícito para evitar ambiguidade.

O bug do ano 2038 afeta o ISO 8601?

Sim para sistemas que armazenam o timestamp como epoch Unix de 32 bits com sinal: esse inteiro estoura em janeiro de 2038. O formato textual ISO 8601 em si não e afetado — o problema esta no armazenamento. Migre para time_t de 64 bits ou guarde como string.

Qual a diferença entre Z e +00:00?

Semanticamente, nenhuma — ambos denotam UTC. Z e mais curto e recomendado pela RFC 3339. Alguns parsers antigos rejeitam Z; outros rejeitam +00:00. Escolha um e seja consistente.

Posso confiar no new Date(str) do JavaScript?

Para entrada ISO 8601 estrita, em geral sim — mas o navegador pode aceitar lixo extra. Para entrada não confiável, valide com regex ou biblioteca antes de construir o Date. A futura Temporal API resolve a maior parte desses tropecos.

Ferramentas Relacionadas