Também disponível em: English · Español · Français · العربية
Códigos de formato strftime: o que cada um produz e quem o define
Escreva uma string de formato, veja o resultado token a token e descubra quais dos seus tokens não sobrevivem a uma troca de plataforma.
O que são os códigos de formato do strftime
strftime é a função da biblioteca C que transforma uma data em texto, e a sua string de formato é uma sequência de caracteres comuns com especificações de conversão no meio. Cada uma é um sinal de porcentagem seguido de uma letra: %Y é o ano de quatro dígitos, %m o mês com zero à esquerda, %d o dia. Tudo que não for conversão é copiado sem alteração, e é por isso que %Y-%m-%d devolve uma data com hifens sem que você precise pedir.
A mesma linguagem aparece muito além do C. Python, Ruby, PHP, R, Perl, awk, o date do GNU e o próprio shell aceitam strings strftime, e a maioria repassa a sua diretamente à biblioteca C da máquina em vez de implementá-la. É exatamente por isso que portabilidade aqui é uma questão viva e não um rodapé: os códigos que o seu programa aceita são decididos pela máquina onde ele roda.
São 42 conversões ao todo, e elas não vêm todas do mesmo lugar. Algumas estão no padrão C de 1989, uma chegou com o C99, doze vêm da Single UNIX Specification, seis do pacote de fusos horários do Olson — o mesmo projeto que fornece o banco de fusos — e uma da própria glibc. Todo resumo publicado achata isso numa lista só, que é justamente a informação de que se precisa quando uma string funciona no seu notebook e não em produção.
Como usar
- Escreva ou escolha uma string de formato. Os botões de exemplo cobrem uma data do dia a dia, uma totalmente portátil, uma linha de log do Apache, a data de semana ISO e uma montada com as duas colisões reais da sintaxe.
- Defina a data e a hora. As duas são lidas como UTC, então o resultado depende só do que você digitou. A tabela de referência lá embaixo é recalculada para o instante que você escolher, o que costuma ser mais rápido que ler uma descrição.
- Leia o detalhamento e as notas. Cada conversão aparece com o padrão que a define e com o que ela produziu. As notas abaixo cobrem o que vale saber: uma flag que não é do POSIX, uma conversão além do C89, ou uma saída que muda com o locale.
Onde a portabilidade realmente quebra, medido
O palpite óbvio é que a linha de perigo é o nível: fique no C89 e você está seguro, saia para a Single UNIX Specification e não está. Medido em duas implementações, essa fronteira quase não morde. O CPython no Windows aceita as 22 conversões do C89 e as 12 da Single UNIX Specification, incluindo %e, %F e %T. Uma página construída em torno das marcações de nível estaria descrevendo um precipício que em boa parte já se erodiu.
O que quebra são as flags, que são um mecanismo à parte sobre o qual as marcações de nível nada dizem. O POSIX define exatamente duas flags, o zero e o sinal de mais, além de uma largura mínima de campo — e em seguida declara que o resultado é indefinido se houver uma flag sem largura mínima, ou uma largura sem flag. Ou seja, até %0d está fora do padrão: o POSIX quer o par, %03d. Já a glibc define cinco flags — sublinhado, hífen, zero, circunflexo e cerquilha — e aceita todas soltas.
É por isso que o truque de strftime mais recomendado da internet é justamente o que quebra. %-d, para tirar o zero à esquerda, é uma extensão da glibc numa forma que o POSIX chama de indefinida, e no CPython sobre Windows ele não degrada em silêncio: levanta ValueError. O mesmo vale para %_d, %s, %P, %k e %l, que o GNU responde sem reclamar.
Os modos de falha são assimétricos, e essa é a parte que vale levar. O Windows erra alto com %-d, o que incomoda mas se corrige sozinho. A saída para a qual a pessoa então apela, %#d, é a grafia da Microsoft para remover o zero à esquerda — e a glibc dá ao mesmo caractere um sentido completamente diferente. Na glibc, a cerquilha é «caso oposto», o que não faz nada a um campo numérico, então %#d volta como 07 e não 7. E não é que a flag seja ignorada: %#A realmente devolve SATURDAY, que é como se sabe que ela está sendo processada. Um caractere, duas definições e nenhum erro dos dois lados.
Duas colisões na sintaxe e uma limitação honesta
O sinal de mais é ao mesmo tempo uma flag do POSIX e uma conversão que a página do manual lista, na mesma posição. Então %+4Y é uma flag com largura, enquanto %+ sozinho é uma conversão que significa a data no formato do date(1). A página do manual resolve a segunda de um jeito incomum: lista a conversão e logo diz que a glibc2 não a suporta. Confirmado: o date do GNU devolve os dois caracteres sem alteração, que é o que esta página também faz.
A outra colisão é %G contra %Y. %G é o ano baseado em semanas do ISO 8601, e ele discorda do ano civil por alguns poucos dias em torno do Ano-Novo. 1 de janeiro de 2027 é uma sexta-feira, então pertence à semana ISO 53 de 2026: %G-W%V dá 2026-W53, enquanto %Y-W%V dá 2027-W53 — uma semana que não existe, porque 2027 tem apenas 52. Varrendo os quarenta anos de 2000 a 2039, os dois discordam em 68 dias de 14.610, ou 0,47 por cento: nunca mais que três dias num mesmo ano, menos de dois em média, e em alguns anos nenhum. Essa é a pior frequência possível para se notar um bug.
A limitação honesta é o locale. Onze das 42 conversões produzem texto que a biblioteca C tira do locale corrente — os nomes de dia e de mês, as marcas de manhã e tarde, e as três que representam uma data ou uma hora inteiras na convenção local. Esta página as renderiza no idioma em que você está lendo, o que é uma resposta razoável e não é a mesma que o seu servidor vai dar. Nada aqui pode dizer como uma máquina com outro locale configurado vai renderizar %c, e uma ferramenta que afirmasse o contrário estaria chutando.
Duas coisas menores. Tudo é formatado como UTC, então %z é sempre +0000 e %Z é sempre UTC; um programa de verdade formata no fuso que recebeu. E %s, os segundos desde a época, está no pacote de fusos e não em nenhum padrão C, e é por isso que é uma das conversões que o Windows recusa de saída.
Por que é grátis?
Transformar uma data em texto é aritmética e uma tabela de consulta, e as duas rodam no seu navegador. Não há servidor no caminho, então não há o que cobrar nem conta a criar.
Nada é enviado. Recarregue a página e ela terá esquecido a sua string de formato.