O problema que todo mundo ignora
A maioria das pessoas acha que saber se um ano é bissexto é só dividir por 4 e ver se sobra zero. Funciona na maior parte dos casos, mas já vi planilhas inteiras de RH quebrarem por causa dessa regra simplificada. Eu estava ajustando um sistema de escala hospitalar há alguns anos quando notei que a tabela de folgas estava com datas deslocadas exatamente três dias. A causa era um ano sé culo que não estava sendo tratado corretamente pelo algoritmo legado do hospital. O sistema usava apenas a regra "divisível por 4", ignorando as exceções. Isso acontece porque o calendário gregoriano, que é o padrão usado na maioria dos países ocidentais desde 1582, tem uma cadeia de regras que não lembram.
O que é ano bissexto e por que ele existe
Um ano bissexto é simplesmente um ano com 366 dias em vez de 365. O dia extra é adicionado ao mês de fevereiro, que passa a ter 29 dias. A razão prática é que o tempo que a Terra leva para dar uma volta completa ao redor do Sol não é exatamente 365 dias. É mais ou menos 365,24219 dias. Se você ignorasse isso, a cada quatro anos o calendário acumularia um dia de defasagem. Em cerca de 700 anos, as estações estariam completamente invertidas no calendário. Junho seria verão no hemisfério norte e inverno no sul, o que causaria problemas sérios para agricultura, navegação e praticamente qualquer atividade baseada em ciclos sazonais. A regra oficial funciona assim: um ano é bissexto se for divisível por 4, exceto quando ele é divisível por 100 mas não por 400. Isso significa que 2024 foi bissexto porque 2024 dividido por 4 dá 506 inteiro. 1900 não foi bissexto porque, apesar de divisível por 4 e por 100, não é divisível por 400. Já 2000 foi bissexto porque atende a todas as condições. Parece complicado, mas o efeito prático dessa exceção centenária é que você perde um dia de bissextos a cada 400 anos. Isso ajusta o calendário com uma precisão de cerca de um dia a cada 3.000 anos.
O que é ano bissexto na prática acaba sendo menos sobre matemática e mais sobre manter orelógios humanos sincronizados com o movimento real do planeta. E essa sincronia não é trivial.
Como calcular na prática
Se você precisa verificar rapidamente se um ano é bissexto, faça esta sequência: verifique se o ano é divisível por 4. Se não for, não é bissexto. Se for, verifique se é divisível por 100. Se não for divisível por 100, é bissexto. Se for divisível por 100, verifique se é divisível por 400. Se for divisível por 400, é bissexto. Se não for, não é. Em código, isso fica com uma linha. Em Python:
(year % 4 == 0 and year % 100 != 0) or (year % 400 == 0) Em qualquer linguagem decente, porém, você raramente precisa escrever isso manualmente. A função datetime ou equivalente já implementa a regra corretamente. O problema é quando pessoas tentam otimizar demais e acabam reimplementando a lógica de forma errada. Eu já vi desenvolvedores escreverem funções personalizadas de verificação de ano bissexto em sistemas de produção. Quase sempre tinha algum bug nas décadas de 1900 ou 2100.
👉 Clique no botão abaixo para saber mais sobre o assunto!
A melhor abordagem é sempre usar a biblioteca padrão da linguagem. O custo de desempenho de chamar uma função embutida é irrelevante, mas o risco de implementar errado existe. Isso vale especialmente para sistemas que operam com datas antes de 1970 ou depois de 2038, onde o tratamento de timestamps pode variar entre plataformas.
Edge cases que machucam
O caso mais comum que eu encontrei na prática envolve sistemas legados que usam o modelo de data do Windows API ou do POSIX. Esses modelos têm diferentes pontos de início. Alguns começam em 1900, outros em 1970. Quando você mistura dados de fontes diferentes, anos como 1900 e 2000 podem ser tratados de formas contraditórias. No sistema hospitalar que mencionei, o problema era específico: o módulo de escalas usava uma biblioteca antiga que considerava 1900 como bissexto, enquanto o banco de dados tratava corretamente. O resultado foram datas de escala deslocadas a cada ciclo de 100 anos. Outro problema real aparece com fusos horários. O dia bissexto nem sempre cai exatamente onde você espera em todos os fusos. A adição do segundo intercalar, quando ocorre, é decidida pelo IERS e depende da rotação real da Terra, que varia. Às vezes a Terra gira mais devagar e é necessário um segundo bissexto, às vezes não. Isso é diferente do dia extra em fevereiro. O segundo intercalar é adicionado ao UTC e pode fazer com que um servidor configurado para atualizar relógios via NTP registre um segundo a mais em qualquer horário do dia, dependendo do fuso local.
Para aplicações críticas, como sistemas financeiros ou de controle de voo, esses segundos intercalares exigem tratamento explícito. Muitos bancos de dados e sistemas operacionais não lidam bem com eles. O workaround que eu uso nesses casos é configurar o relógio do sistema para usar o modo "leap smear", que espalha o segundo extra ao longo de 24 horas em vez de inseri-lo de uma vez. Isso evita quedas em processos que não esperam um segundo a mais no meio de uma operação.
O que ninguém te conta sobre anos bissextos
Uma coisa contra intuitiva é que anos bissextos não tornam o ano médio exatamente igual ao ano trópico. O ano trópico atual é de aproximadamente 365,24219 dias. A regra gregoriana produz um ano médio de 365,2425 dias. A diferença é pequena, mas significa que o calendário gregoriano ainda ganha cerca de um dia a cada 3.200 anos em relação ao movimento real da Terra. Houve propostas para ajustar a regra, removendo bissextos nos anos divisíveis por 4000, mas nenhuma foi adotada oficialmente. Outro ponto que as pessoas ignoram: o dia bissexto em fevereiro é uma herança romana que não reflete nada natural. O mês de fevereiro foi o último mês do calendário romano original e recebeu dias extras justamente para "limpar" o Ano Novo. Historicamente, a posição de fevereiro como mês com menos dias é arbitrária. Sistemas de computação que usam o número de dias no ano (365 ou 366) como chave de partições em bancos de dados muitas vezes quebram sem aviso. Eu recomendo usar o número de dias no mês em vez do total anual quando possível, pois a variação de fevereiro é isolada e previsível.
Se você está construindo algo que precisa lidar com anos bissextos, a primeira decisão é se vai usar uma biblioteca estabelecida ou escrever sua própria lógica. A menos que você tenha necessidades muito específicas, como suporte a calendários históricos ou astronomia de precisão, usar a biblioteca padrão é quase sempre a escolha certa. Escrever sua própria implementação só faz sentido se você estiver em um ambiente extremamente restrito, como embarcados com memória limitada, e mesmo assim deve ser testado contra casos de borda antes de ir para produção.