O que aconteceu quando os computadores chegaram em 2000
a maioria das pessoas ainda associa y2k: o bug do milênio a filmes de terror com prédios caindo e aviões batendo no mar. a realidade foi bem mais chata e bem mais interessante ao mesmo tempo. basicamente, programadores dos anos 80 e 90 economizaram espaço dizendo que o ano seria apenas dois dígitos. Então 98 era 1998, 99 era 1999. Quando chegou 2000, o sistema via 00. Ponto. eu trabalhei com manutenção de sistemas legados numa empresa de logística em 1999. O trabalho não era dramático. Era planilha,era código COBOL, era conversar com desenvolvedores que já tinham saído da empresa há três anos. A coisa mais difícil não era consertar o bug, era descobrir onde ele existia.
y2k: o bug do milênio e como a gente resolveu na prática
o processo real de correção era assim: primeiro você fazia uma varredura completa do código-fonte procurando por expressões regulares que capturassem padrões de data. Duas posições numéricas, quatro posições, campos fixos em arquivos texto. Depois mapeava cada ocorrência para entender se ela era apenas visual ou se afetava lógica de negócio. Tratamentos visuais eram triviais. Lógicos pesavam. eu tenho um caso específico que ficou gravado. Tínhamos um sistema de folha de pagamento que calculava férias e 13º com base no mês de entrada do funcionário. A data estava armazenada em dois campos inteiros separados: mês e ano. O campo ano tinha quatro dígitos, mas o cálculo usava subtração direta entre o ano atual e o ano de entrada. Quando o ano virou 2000, a conta simplesmente funcionou, porque o sistema já usava quatro dígitos naquela parte. O problema estava noutra module, numa rotina de validação de contrato que comparava datas usando string. Dois dígitos. A validação dizia que todo contrato assinado em 2000 estava inválido porque 00 era menor que qualquer ano vigente.
a solução foi substituir a comparação de string por uma conversão para timestamp antes de comparar. Não era elegante, mas funcionou sem reescrever a module inteira. Eu passei duas semanas só caçando essas discrepâncias num módulo que não eu mesmo tinha escrito.
como identificar sistemas vulneráveis
a primeira coisa é saber o que procurar. Sistemas vulnerable geralmente têm pelo menos um destes sinais: dados de data armazenados como strings de dois dígitos, uso de funções que assumem ano base fixo (como Date() no JavaScript sem especificar ano completo), arquivo com campos fixos onde o ano ocupa duas posições, e integrações entre sistemas que não foram modernizados juntos. eu costumava usar scripts em perl pra varrer diretórios inteiros. Um regex simples como /\b(0[1-9]|1[0-2])([0-9]{2})/ pegava a maioria dos casos óbvios. Para COBOL, o problema era mais complexo porque campos date podiam estar em cláusulas USAGE DISPLAY com tamanho fixo. Aí eu precisava inspecionar o layout físico do arquivo, não apenas o código.
👉 Clique no botão abaixo para saber mais sobre o assunto!
um detalhe que poucos consideram: bugs de ano bissexto. Muitos sistemas simplesmente não tratavam anos bissextos corretamente. Se a data 29 de fevereiro de 2000 aparecesse num cálculo, o sistema podia arredondar para 01 de março ou erro fatal, dependendo da linguagem e da implementação. Isso causava falhas em relatórios mensais e agendamentos automáticos que ninguém perceb immediately porque o bug só aparecia naquele dia específico.
testes que realmente importavam
não adiantava só rodar o software e ver se abria. O teste verdadeiro era forçar datas extremas e observar o comportamento. Eu criava arquivos de teste com datas como 29/02/2000, 31/12/1999, 01/01/2000 e 01/01/2001 passando por todas as rotinas críticas do sistema. Se algo quebrasse numa dessas transições, você tinha achado um bug real. o problema é que muitos ambientes de produção nunca receberam esse tipo de teste. Sistemas rodavam 24 horas, não havia janela de manutenção, e a pressão era enorme porque ninguém podia parar a operação. Eu vi cenários onde o time de QA fez testes unitários isolados que passaram todos, mas a integração entre três módulos diferentes gerava resultados completamente errados quando a data cruzava o ano. Isso acontece porque o bug só aparece com fluxo de dados real, não com entradas isoladas.
alternativas e limitações
a correção mais segura é transformar todos os campos de data em formato ANSI YYYYMMDD ou usar timestamps Unix (segundos desde 01/01/1970). Timestamps resolvem o problema de forma elegante porque são números inteiros e não dependem de formatação de string. A desvantagem é que readable humans não conseguem ler timestamps diretamente e você precisa de ferramentas de conversão constante. para sistemas muito antigos, nem sempre é possível aplicar timestamp. Linguagens como COBOL e Pascal têm limitações nativas que tornam a migração cara. Nesses casos, a alternativa era um patch de extensão de ano: alterar a interpretação de dois dígitos para considerar que 00 a 49 pertencem a 2000 a 2049 e 50 a 99 a 1950 a 1999. Isso resolvia a maior parte dos casos sem reescrever código, mas criava problemas futuros quando se chegasse a 2050, e ninguém lembrava disso na época.
um ponto cego importante: bancos de dados que usavam tipos de data com range limitado. SQL Server por exemplo, na versão 6.5, aceitava datas a partir de 1753. Se o sistema legava armazenar datas anteriores a 1900, o banco já rejeitava antes mesmo do problema do ano 2000 existir. Isso significava que correções de Y2K em sistemas antigos às vezes precisavam migrar o banco inteiro primeiro, o que duplicava o trabalho e o tempo de paralisação.
lições que ficaram
o bug do milênio ensinou algo útil que ainda se aplica hoje: documentação de formatos de dado é mais importante que o código em si. Se alguém documentar que um campo usa formato DDMMYY, o próximo desenvolvedor não vai perder três dias caçando um bug que era só má interpretação de formato. Infelizmente isso raramente acontece na prática. também aprendi que a correção mais barata nem sempre é a mais completa. Patch de extensão de ano foi suficiente para a maioria das empresas em 1999. Sistemas críticos como aeroespacial e financeiro tiveram orçamentos maiores e refizeram tudo do zero. A diferença no resultado final era pequena, mas a diferença no custo era enorme. Escolher o nível certo de correção foi talvez a decisão mais importante daquele período.