Alguns equívocos de programação sobre o tempo



Certamente você tem certeza de que algumas - senão todas - dessas declarações são verdadeiras sempre e em todos os lugares:



  • Sempre há 24 horas em um dia.
  • Uma semana sempre começa e termina no mesmo mês.
  • Uma semana (ou mês) sempre começa e termina no mesmo ano.
  • O tempo não tem começo nem fim.
  • Pode haver 28, 29, 30 ou 31 dias em um mês.
  • Há um ano bissexto a cada 4 anos.
  • Em cada mês, o número de dias é sempre o mesmo em todos os lugares.
  • O servidor e o cliente terão sempre o mesmo horário.
  • Você pode calcular facilmente o número de horas e minutos a partir de algum ponto no tempo.
  • Cada minuto tem 60 segundos.


Embora a prática mostre que é uma ilusão confiar na verdade dessas declarações ao desenvolver software. Bem, ok, nem todos esses pontos são equívocos . Algumas das afirmações seriam verdadeiras se não fossem os bugs irritantes e casos extremos, que se acumularam ao longo da história do software.



Cada minuto tem 60 segundos e sempre há 24 horas em um dia



Por exemplo, em versões mais antigas do KVM no CentOS, havia um bug curioso - um minuto pode durar o tempo que você quiser. O fato é que o KVM não sabia que não estava rodando no hardware físico, e se o SO host suspendeu temporariamente a máquina virtual, então o relógio virtualizado continuou a funcionar a partir do momento em que foi suspenso . Por exemplo, se um carro foi pausado às 13:00 e ativado às 15:00, o relógio do sistema continuou a mostrar 13:00. Como resultado, após cada pausa, havia uma discrepância com o tempo real. Havia até uma tarefa cron que poderia ser configurada para sincronizar o relógio virtualizado com o relógio do hardware. Mas, ao criar uma nova máquina virtual, era fácil esquecê-la e era divertido. O bug foi corrigido posteriormente.



Além dos bugs, há também um segundo bissexto (extra) de segundo: é adicionado ao UTC (Tempo Universal Coordenado) no final do dia 30 de junho ou 31 de dezembro para compensar a desaceleração gradual da rotação da Terra e o acúmulo da diferença entre os dias SI e astronômicos - ensolarado - por dias.



Quanto à duração do dia, o principal inimigo do programador é a transição para o horário de verão, que está em algum lugar lá, em algum lugar onde não está, e antes disso poderia ser cancelado ou introduzido. Este é um grande problema separado com dados históricos - horário de verão.



E se somarmos a isso a mudança de fusos horários ...





Cerca de semanas, meses e anos



Mas histórias sobre diferentes durações de meses e anos estão associadas a diferentes cálculos de calendário para diferentes povos do mundo. Por exemplo, o calendário hebraico opera com meses lunares: isto é, o início e o fim do mês estão ligados às fases da lua. Você acha que pode facilmente levar isso em consideração adicionando um ajuste para Israel com o carregamento das fases lunares? Não funciona. Em um ano bissexto judaico, um mês extra é adicionado . Além disso - cuidado com as mãos - os anos simples e bissextos no calendário hebraico podem ter três durações diferentes . No total, um ano pode ter seis durações diferentes.de 354 a 383 dias. Você acha que foi aqui que as diferenças em relação ao nosso calendário terminaram? Onde há: no calendário judaico, os dias têm durações diferentes e são contados do pôr do sol ao pôr do sol (formalmente, quando três estrelas se tornam visíveis no céu).



Você acha que é só para os judeus que nem tudo é como no calendário gregoriano (à questão da Grande Revolução Socialista de Outubro, que foi celebrada na URSS em 7 de novembro)? Nos países árabes:



  • A semana não começa na segunda-feira, mas no domingo.
  • O fim de semana é considerado sexta-feira e sábado, e em alguns países - quinta e sexta-feira. Nos últimos 10 anos, alguns estados mudaram o fim de semana para sexta e sábado para facilitar o comércio internacional. E ainda assim, nem todos os países árabes têm um fim de semana de dois dias.
  • Os feriados religiosos dependem de observações do ciclo lunar, portanto, seu tempo não pode ser previsto com precisão.


Quanto ao fato de que semanas e meses podem terminar no próximo ano, isso é novamente típico de países com calendários lunar e solar-lunar - neles, o ano novo não começa em 1º de janeiro. De imediato, você pode se lembrar imediatamente dos chineses, cujo ano novo começa no período de 21 de janeiro a 21 de fevereiro de acordo com o calendário gregoriano. E no calendário etíope, o ano novo é geralmente 29 ou 30 de agosto, e até mesmo o número de anos que eles têm é 8 a menos do que no sistema "desde o nascimento de Cristo".



O servidor e o cliente terão sempre o mesmo horário



E aqui está um fato interessante, devido ao qual a hora em diferentes computadores pode não só não coincidir, mas até mesmo o tamanho da discrepância pode variar. Quando o Linux é inicializado, ele leva o tempo de hardware atual e, em seguida, faz a contagem regressiva ainda mais, adicionando dados do relógio do processador interno (TSC). Esses relógios podem ser bastante imprecisos. Por exemplo, devido à escala do relógio, que altera dinamicamente a frequência do TSC. E se você alterar a frequência do relógio no host, todas as contas de convidados nem perceberão. Se você escalar a frequência do TSC em 50%, o tempo começará a funcionar duas vezes mais lento. Além disso, em alguns servidores, o BIOS pode dimensionar a frequência do processador sem notificar o sistema operacional, o que também adiciona um erro. Em processadores mais novos, as frequências TSC agora são fixas. A propósito, o Windows não usa TSC, então este sistema operacional tem outros problemas com o tempo:)



Você pode calcular facilmente o número de horas e minutos a partir de algum ponto no tempo



A menos que haja algo como Python na linguagem de programação tzinfo()



, você não pode obter uma data e hora específicas simplesmente adicionando horas e minutos a alguma data no passado. É necessário levar em consideração os fusos horários (e suas possíveis mudanças, como já aconteceu mais de uma vez na história), depois levar em consideração todas as mudanças na transição para o horário de verão ... No Windows, isso geralmente é impossível, porque a Microsoft fornece apenas o início e o final do ano atual. Surpreendentemente, depois de tantos patches de manipulação de DST, a empresa ainda não implementou um equivalente do Windows tzinfo()



. Provavelmente não.



O tempo não tem começo e não tem fim



"Seu programa nunca precisará lidar com datas anteriores a 1970." Em sistemas Unix (incluindo Linux e iOS), o tempo é contado em segundos desde 00:00:00 em 1 de janeiro de 1970 UTC (Coordinated Universal Time). Qualquer coisa anterior no Unix já será hora negativa. Além disso, a hora é representada em uma expressão inteira de 32 bits e a data mais antiga possível em sistemas Unix é 13 de dezembro de 1901. E o tempo Unix "top" é limitado a 19 de janeiro de 2038, quando o número de segundos desde o início da contagem regressiva chega a 2 31 , e esse número pode ser considerado negativo pelo sistema.







Tudo isso é apenas uma pequena parte do grande número de nuances e bugs com os quais os desenvolvedores de qualquer produto demorado precisam lidar. Certamente você também tem uma história para contar de sua experiência, escreva nos comentários.



All Articles