Escrever uma data em ISO 8601 e porque é o único formato sem ambiguidade
Publicado a 13/08/2026 · 16 min de leitura · Ferramentas de texto e idioma
Daniel Okonkwo — Programador front-end e redator de Tecnologia na OneKitly
Desempenho web · Formatos de ficheiro
Verificado a partir de 4 fontes
Escreva primeiro o ano, depois o mês, depois o dia, cada um com zeros à esquerda: 2026-02-01. A ordem é todo o truque. Como os campos vão da unidade maior para a menor e cada um tem largura fixa, comparar duas cadeias carácter a carácter dá a mesma resposta que comparar os dois instantes — e é por isso que ordenar uma pasta de ficheiros assim nomeados os deixa em ordem cronológica sem qualquer lógica de datas. A hora liga-se à data com um T maiúsculo e acrescenta-se um desvio em relação ao UTC: 2026-02-01T09:30:00+01:00, ou Z quando o desvio é zero. Uma data-hora sem desvio é uma data local cujo sentido depende de onde é lida, precisamente a ambiguidade que o formato existe para eliminar, portanto acrescente o desvio a não ser que queira mesmo falar de um relógio de parede. A ferramenta foi passada por isto: guarda um instante como sete inteiros e converte com aritmética inteira em vez de um objeto Date, pelo que 2026-08-13T00:30:00+02:00 volta como 2026-08-12T22:30:00Z, um dia antes e correto, com um timestamp Unix de 1786573800 idêntico ao Date.UTC. O seu botão «Agora» lê o relógio em UTC, portanto logo depois da meia-noite em Paris preenche a data do dia anterior: surpreendente, não errado. Dois avisos. A ordenação textual só equivale à temporal se todas as cadeias levarem o mesmo desvio; misture Z e +02:00 e a ordem fica errada em silêncio. E a ISO 8601 é mais ampla do que a RFC 3339, que é o que a maioria das API exige de facto: uma data só, uma data de semana, uma cadeia em formato básico e uma hora 24 são ISO 8601 válida, e nenhuma é RFC 3339 válida.
01/02/2026 é 1 de fevereiro na maior parte da Europa e 2 de janeiro nos Estados Unidos, e nada na cadeia diz qual. A ISO 8601 resolve isso, ordena-se como texto, e deixa de servir em quatro pontos concretos que a RFC 3339 recusa.
01/02/2026 e os seis idiomas em que este site está escrito
Um leitor em Paris, Madrid, Lisboa, Berlim ou Roma lê 01/02/2026 como 1 de fevereiro. Um leitor nos Estados Unidos lê os mesmos oito algarismos como 2 de janeiro. Nada na cadeia decide entre os dois: as duas leituras são completas, as duas são convencionais, e as duas erram cerca de metade das vezes assim que a cadeia viaja.
A falha é silenciosa, e é isso que a torna cara. Um formulário aceita a data, uma base guarda-a, um relatório imprime-a, e nada protesta até ao dia doze do mês, quando as duas leituras deixam de produzir cada uma uma data válida e uma acaba por lançar um erro. Tudo o que estava entre o dia 1 e o dia 12 foi deslocado em silêncio. Uma entrega prevista para 3 de abril chega a 4 de março, uma fatura fica datada onze meses antes, e o registo de auditoria guarda ambas como lançamentos perfeitamente normais.
2026-02-01 não tem segunda leitura. O ano vem primeiro por ser a unidade maior, o mês a seguir, o dia por último, e cada um é preenchido a uma largura fixa. Não há locale a consultar, nem convenção de separador a adivinhar, nem mês que possa passar por dia. É todo o contributo da norma, e chega.
Ordenar como texto e ordenar no tempo são a mesma operação
Ordene os campos do maior para o menor, preencha cada um a uma largura fixa, e a comparação lexicográfica passa a ser de graça uma comparação cronológica. Cinco instantes foram passados pela ferramenta, ordenados uma vez como cadeias e outra pelos seus timestamps Unix: as duas ordens foram idênticas. É essa propriedade que faz com que uma pasta de ficheiros chamados 2026-02-01-notas.md, 2026-02-11-notas.md e 2026-10-02-notas.md fique na ordem certa em qualquer gestor de ficheiros, qualquer shell e qualquer listagem de cópias de segurança, sem nenhuma análise de datas em toda a cadeia.
A propriedade tem uma condição fácil de perder: todas as cadeias têm de levar o mesmo desvio. Passaram-se dois instantes para o mostrar. 2026-01-05T09:00:00Z e 2026-01-05T10:00:00+02:00 ordenam-se por essa ordem como texto, porque o carácter 9 precede o carácter 1 seguido de 0. Os seus timestamps Unix são 1767603600 e 1767600000, portanto o segundo aconteceu primeiro. A ordem textual está errada e nada o assinala. Se uma coluna puder conter desvios misturados, normalize tudo para Z antes de ordenar, ou ordene pelo timestamp.
O mesmo raciocínio explica a convenção de nomes de ficheiro. Ponha a data no início do nome e a pasta ordena-se sozinha; ponha-a no fim e ordena-se pelo que a precede. Use hífenes e não barras, porque a barra é separador de caminhos em todos os sistemas, e os dois pontos — legais numa hora mas proibidos num nome de ficheiro no Windows — explicam porque um nome com data e hora costuma cair em 2026-02-01T093000Z, o formato básico que a norma também define.
O T, o Z e um desvio que não é um fuso horário
O T maiúsculo liga a data à hora. Está lá porque uma data e uma hora são duas representações distintas e alguma coisa tem de dizer onde uma acaba e a outra começa; um espaço serviria para uma pessoa, e é exatamente o que uma base de dados imprime, mas a norma estrita quer o T. O Z final significa desvio zero — Zulu, do alfabeto fonético militar — e é permutável com +00:00.
Um desvio como +02:00 diz quanto o relógio de parede se afasta do UTC naquele instante, e nada mais. Não nomeia Paris: é também o Cairo, Joanesburgo, Helsínquia e metade da Europa no mesmo momento, e o mesmo relógio parisiense está a +01:00 em janeiro. É por isso que um compromisso futuro tem de ser guardado como identificador de fuso — Europe/Paris — com a hora local, e não como um desvio. Guarde 2027-03-28T10:00:00+01:00 para uma reunião e ela será às nove da manhã depois da mudança da hora, coisa que ninguém combinou.
Uma data-hora sem qualquer desvio é uma data local, e o seu sentido é o que a máquina do leitor decidir. É ISO 8601 válida e por vezes é o que se quer — uma loja abre às 09:00 na cidade onde está — mas não é um instante, e tratá-la como tal é a maneira como uma linha de registo vinda de um servidor estrangeiro chega à hora errada, e como uma data de nascimento numa base passa a ser o dia anterior para quem está a oeste do meridiano.
À caça do desvio de um dia à volta da meia-noite, sem o encontrar
O defeito mais comum em ferramentas de datas é uma conversão que passa pelo fuso local do navegador e cai um dia ao lado perto da meia-noite. Esta não o tem, por uma razão estrutural: nunca toca na hora local. Um instante é guardado como sete inteiros — ano, mês, dia, hora, minuto, segundo e desvio em minutos — e a conversão para UTC desloca o número do dia com aritmética inteira em vez de construir um Date. O botão «Agora» lê o relógio com getUTCFullYear e as suas irmãs e fixa o desvio em UTC+00:00.
Os casos-limite foram passados de propósito. Paris às 00:30 de 13 de agosto com desvio +02:00 dá uma forma UTC 2026-08-12T22:30:00Z e uma data HTTP Wed, 12 Aug 2026 22:30:00 GMT — um dia antes, o que é correto, porque é o mesmo instante. Nova Iorque às 23:30 de 12 de agosto com desvio −04:00 vai no sentido inverso, para 2026-08-13T03:30:00Z. As ilhas Chatham às 00:10 de 1 de janeiro com desvio +12:45 saem como 2025-12-31T11:25:00Z, atravessando ao mesmo tempo um dia e um ano. Cinco destes casos foram cruzados com Date.UTC, incluindo o 1969-07-20T20:17:40Z anterior à época, cujo timestamp de −14 182 940 coincidiu exatamente.
A única coisa que parece um desvio de um dia é o botão «Agora», e é uma escolha deliberada que transparece. Como o relógio é lido em UTC, um leitor parisiense que o carregue à meia-noite e meia de 13 de agosto vê o campo da data preenchido com 12 de agosto e a hora com 22:30. É o mesmo momento expresso no fuso por omissão da ferramenta, não a data de ontem. Se quiser o seu próprio relógio de parede, escreva a data e a hora à mão e escolha o seu desvio na lista.
A RFC 3339 é o que a sua API quer dizer, e é mais estreita
Quando uma API diz que quer ISO 8601, quase sempre quer RFC 3339, que se descreve a si própria como um perfil da ISO 8601 para uso na Internet. Um perfil é um subconjunto: tudo o que a RFC 3339 aceita é ISO 8601, e boa parte da ISO 8601 não é RFC 3339. A sua gramática exige uma data completa, depois um T, depois uma hora completa e depois um desvio — nada pode ser omitido.
Quatro diferenças importam na prática, todas legíveis na própria gramática da RFC. A sua hora é definida como dois algarismos entre 00 e 23, portanto 24:00 — fim de dia legal em ISO, que designa o mesmo instante que a meia-noite do dia seguinte — não é RFC 3339. O seu desvio escreve-se sinal, dois algarismos, dois pontos e mais dois algarismos: +0200 e +02 são ISO 8601 e nenhum é RFC 3339. Não tem datas de semana nem datas ordinais, logo 2026-W33-4 e 2026-225 ficam de fora. E uma data nua como 2026-08-13, ou um ano e um mês, ou um ano sozinho, não é sequer uma data-hora segundo a RFC 3339.
Duas subtilezas vão no sentido contrário, onde a RFC 3339 é mais permissiva. Dá a −00:00 um sentido próprio: a hora UTC é conhecida mas o desvio local não, o que é deliberadamente diferente de Z ou de +00:00. E uma nota da mesma secção diz que as aplicações podem usar um espaço em vez do T por legibilidade, que é exatamente o que as bases de dados imprimem. A ferramenta aceita um espaço colado e avisa que o viu; também aceita −00:00 e transforma-o em silêncio em Z, de modo que a distinção traçada pela RFC não sobrevive a uma ida e volta.
Uma consequência merece ser assinalada, porque a ferramenta não o faz. O seu campo de saída principal, o rotulado como forma estendida de data e hora, é RFC 3339 sempre que a hora esteja entre 00 e 23 — e não é quando a hora vale 24, o que o analisador aceita. Cole 2026-08-13T24:00:00Z e esse campo devolve-lho tal e qual, e o campo rotulado como data de e-mail imprime uma hora que a RFC 5322 também não permite. A linha UTC ao lado está certa: indica 2026-08-14T00:00:00Z. Se estiver a copiar um valor para uma API, copie esse.
Datas de semana, datas ordinais e as pequenas coisas que a ferramenta erra
A ISO 8601 define mais duas formas de data e a ferramenta imprime ambas. Uma data de semana nomeia o ano, a semana e o dia da semana, e o seu ano nem sempre é o ano civil: uma semana pertence ao ano que contém a sua quinta-feira. Passe 1 de janeiro de 2027 pela ferramenta e volta como 2026-W53-5; passe 31 de dezembro de 2024 e volta como 2025-W01-2. Ambos foram verificados. Uma data ordinal nomeia o ano e o dia dentro dele, portanto 13 de agosto de 2026 é 2026-225. As duas ordenam-se lexicograficamente tão bem como as datas civis — mas nunca misture as três formas numa mesma coluna, porque 2026-W33-4 e 2026-08-13 ordenam-se entre si como cadeias, sem qualquer relação com o tempo.
Três pequenos defeitos apareceram nos testes e vale a pena conhecê-los mais do que temê-los. Um segundo de 60 é aceite em qualquer sítio — cole 2026-08-13T00:30:60Z e a ferramenta aceita-o e calcula um timestamp Unix de 1786581060, que são as 00:31:00 — ao passo que tanto a norma como a RFC só admitem 60 sob as regras do segundo intercalar. As frações de segundo são lidas e depois deitadas fora: 2026-08-13T00:30:00.123Z volta como 2026-08-13T00:30:00Z, sem qualquer aviso de que os milissegundos desapareceram. E o analisador de durações rejeita P0D, uma duração zero perfeitamente legal, porque descarta toda a duração cujos campos sejam todos zero.
O que faz bem merece a mesma frase. Recusa 2026-02-30 e 2026-08-13T25:00:00Z, recusa um 2026-8-3 sem preenchimento, e recusa liminarmente 13/08/2026 e 08/13/2026, que é a resposta certa para uma ferramenta cujo trabalho é dizer o que é e o que não é ISO 8601. Lê o formato básico 20260813T003000+0200, lê um t e um z minúsculos, e diz-lhe qual das três formas de data reconheceu. As durações também são analisadas corretamente, incluindo a vírgula decimal de P1,5D, que normaliza para P1.5D.
| Cadeia | Estado | Porquê |
|---|---|---|
| 2026-08-13T00:30:00+02:00 | Ambas | Data completa, T, hora completa, desvio com dois pontos — exatamente a gramática RFC 3339 |
| 2026-08-13 | Só ISO 8601 | A RFC 3339 define uma data-hora, não uma data sozinha |
| 2026-W33-4T12:00:00+02:00 | Só ISO 8601 | As datas de semana não estão na gramática RFC 3339; a ferramenta lê-a como 13 de agosto de 2026 |
| 20260813T003000+0200 | Só ISO 8601 | O formato básico retira os separadores; a RFC 3339 exige-os |
| 2026-08-13T24:00:00Z | Só ISO 8601 — e a ferramenta reimprime-o | A RFC 3339 fixa a hora entre 00 e 23; a linha UTC mostra corretamente 2026-08-14T00:00:00Z |
| 2026-08-13 00:30:00Z, com um espaço | RFC 3339 por uma nota; a ferramenta aceita-o e assinala-o | Uma nota da secção 5.6 permite um espaço por legibilidade; a norma estrita quer o T |
| 2026-08-13T00:30:00-00:00 | Só RFC 3339; a ferramenta transforma-o em Z | A secção 4.3 dá-lhe o sentido «desvio desconhecido», que a conversão apaga |
| 2026-08-13T00:30:60Z | Nenhuma, e a ferramenta aceita-o | Um segundo de 60 é um segundo intercalar, só às 23:59:60; o timestamp sai como 00:31:00 |
| 13/08/2026 e 08/13/2026 | Nenhuma; a ferramenta recusa as duas | A ambiguidade que toda a norma existe para eliminar — recusar é a resposta certa |
Perguntas frequentes
- Devo escrever o desvio ou usar Z em toda a parte?
- Para tudo o que guardar, registar ou enviar entre máquinas, normalize para Z. Cada valor leva então o mesmo desvio, logo a ordenação textual equivale à temporal, as comparações não precisam de conversão e não há nada a errar. Guarde o desvio local só quando a leitura local for ela própria o facto: um recibo que deva dizer que a transação ocorreu às 09:15 na manhã da loja, uma partida de comboio impressa para os passageiros. E para um compromisso futuro, nenhum dos dois serve: guarde o identificador de fuso e a hora local, porque o desvio que esse fuso terá naquela data é uma decisão que ainda ninguém tomou.
- A ISO 8601 e a RFC 3339 são a mesma coisa?
- Não. A RFC 3339 apresenta-se como um perfil da ISO 8601 para protocolos da Internet, e um perfil é um subconjunto. A sua gramática só admite a data de calendário, exige a presença da hora e do desvio, limita a hora entre 00 e 23, e escreve o desvio com dois pontos e minutos obrigatórios. Assim, uma data nua, uma data de semana como 2026-W33-4, uma data ordinal como 2026-225, o formato básico sem hífenes, uma hora de 24 e um desvio escrito +0200 ou +02 são todos ISO 8601 válida e nenhum é RFC 3339 válida. No sentido contrário, a RFC 3339 dá a -00:00 um sentido próprio — a hora UTC é conhecida mas o desvio local não — e permite t e z minúsculos. Quando uma API pede ISO 8601, envie RFC 3339 e satisfará as duas.
- Porque é que a ferramenta mostra a data de ontem quando carrego em «Agora»?
- Porque lê o relógio em UTC e fixa o desvio em UTC+00:00, não porque tenha contado mal. Se está a leste de Greenwich e é pouco depois da meia-noite, o seu relógio de parede já está no dia novo enquanto o UTC ainda está no antigo. Um leitor parisiense que carregue em «Agora» às 00:30 de 13 de agosto vê preenchidos 12 de agosto e 22:30 — o mesmo momento, expresso no fuso por omissão da ferramenta. Nada da conversão passa pelo fuso da sua máquina: o instante é guardado em inteiros e deslocado com aritmética inteira, e cinco casos-limite, incluindo uma data anterior à época e um desvio de +12:45, coincidiram exatamente com o Date.UTC. Se quiser a sua hora de parede, escreva a data e a hora e escolha o seu desvio na lista.
- Posso mesmo ordenar datas ordenando o texto?
- Sim, com uma condição: todas as cadeias têm de ter a mesma forma e o mesmo desvio. Ordenaram-se cinco instantes das duas maneiras com a ferramenta e as ordens foram idênticas. Quebre a condição e falha em silêncio: 2026-01-05T09:00:00Z ordena-se antes de 2026-01-05T10:00:00+02:00 como texto, mas os seus timestamps são 1767603600 e 1767600000, portanto o que fica em segundo aconteceu primeiro. Misturar datas civis com datas de semana quebra-o igualmente, já que 2026-W33-4 se compara com 2026-08-13 como duas cadeias sem significado comum. Normalize para Z e para uma só forma antes de ordenar, e o truque é completamente seguro — que é precisamente por isso que é a maneira certa de nomear ficheiros.
- Porque é que 1 de janeiro de 2027 se escreve 2026-W53-5?
- Porque uma semana pertence por inteiro a um só ano, e a norma dá-a àquele que contém a sua quinta-feira. A semana que inclui 1 de janeiro de 2027 tem a sua quinta-feira a 31 de dezembro de 2026, portanto toda a semana é a semana 53 do ano de numeração 2026, e a sexta-feira que contém é o dia 5. A mesma regra joga no sentido inverso: 31 de dezembro de 2024 sai como 2025-W01-2, ambos verificados na ferramenta. Duas consequências práticas. O ano de numeração das semanas não é o ano civil e nunca deve ser colado a um mês civil num título de relatório. E um ano tem 53 semanas quando o seu 1 de janeiro cai numa quinta-feira, ou numa quarta-feira de ano bissexto — 2026 tem 53, 2027 tem 52 — de modo que um gráfico com 52 colunas fixas desloca uma semana a cada cinco ou seis anos.
Artigos que podem interessar-lhe
Todos os guias →Ferramentas relacionadas
Tudo o que se segue descreve o que estas quatro ferramentas fazem hoje, verificado executando o seu próprio código sobre as entradas exatas reproduzidas em cada artigo, e não o que uma norma as obrigue a fazer. Quando uma ferramenta erra num caso, fica escrito com clareza em vez de contornado, e nada foi alterado para um artigo ler melhor. Duas consequências. Passe qualquer transformação primeiro por uma cópia e compare as duas pontas: uma ferramenta de texto que apaga alguma coisa não o anuncia. E dê um segredo por partilhado assim que ele sai da página: colá-lo numa conversa, num ticket ou num repositório queima-o, por melhor que tenha sido gerado.
Fontes
- IETF — RFC 3339 — Date and Time on the Internet: Timestamps (§5.6 grammar, §4.3 unknown local offset)
- IETF — RFC 9557 — Timestamps with Additional Information, which extends RFC 3339 with a zone identifier
- WHATWG — HTML Standard — dates and times: the date, time and datetime microsyntaxes browsers accept
- MDN Web Docs — Date.prototype.toISOString() — the simplified extended format JavaScript emits
Detetaste um erro neste artigo?