Uma maneira de pensar sobre isso é o que você quer dizer com hora / data ? Os computadores não sabem quais são esses conceitos: eles precisam ser programados de alguma forma. É bastante comum representar tempos no formato UNIX de "segundos desde a época", e é comum alimentar um valor específico em um programa por meio de chamadas do SO. No entanto, não importa quão comum seja esse uso, é importante ter em mente que não é a hora "real": é apenas uma representação lógica.
Como outros já apontaram, se você fez um "prazo" usando esse mecanismo, é trivial alimentar um horário diferente e quebrar esse "prazo". O mesmo vale para mecanismos mais elaborados, como solicitar a um servidor NTP (mesmo em uma conexão "segura", pois podemos substituir nossos próprios certificados, autoridades de certificação ou até corrigir as bibliotecas de criptografia). A princípio, pode parecer que essas pessoas são as culpadas por contornar seu mecanismo, mas pode ser o caso de ser feito automaticamente e por boas razões . Por exemplo, é uma boa ideia ter construções reproduzíveis e ferramentas para ajudar a isso podem redefinir / interceptar automaticamente chamadas de sistema não determinísticas. libfaketime faz exatamente isso,define todos os carimbos de data e hora do arquivo 1970-01-01 00:00:01
, o recurso de gravação / reprodução do Qemu falsifica toda a interação do hardware, etc.
Isso é semelhante à lei de Goodhart : se você faz o comportamento de um programa depender do tempo lógico, então o tempo lógico deixa de ser uma boa medida do tempo "real". Em outras palavras, as pessoas geralmente não mexem com o relógio do sistema, mas sim se você lhes der um motivo.
Existem outras representações lógicas do tempo: uma delas é a versão do software (seu aplicativo ou alguma dependência). Essa é uma representação mais desejável para um "prazo" do que, por exemplo, o horário do UNIX, já que é mais específica para o que lhe interessa (alteração de conjuntos de recursos / APIs) e, portanto, é menos provável que atropele preocupações ortogonais (por exemplo, mexendo no tempo do UNIX para contornar o prazo pode acabar quebrando arquivos de log, tarefas cron, caches, etc.).
Como já foi dito, se você controla a biblioteca e deseja "enviar" essa alteração, pode enviar uma nova versão que descontinua os recursos (causando avisos, para ajudar os consumidores a encontrar e atualizar seu uso) e, em seguida, outra nova versão que remove o apresenta inteiramente. Você pode publicá-las imediatamente uma após a outra, se quiser, uma vez que (novamente) as versões são meramente uma representação lógica do tempo, elas não precisam estar relacionadas ao tempo "real". O controle de versão semântico pode ajudar aqui.
O modelo alternativo é "puxar" a mudança. É como o seu "plano B": adicione um teste ao aplicativo consumidor, que verifica se a versão dessa dependência é pelo menos o novo valor. Como sempre, vermelho / verde / refatorar para propagar essa alteração pela base de código. Isso pode ser mais apropriado se a funcionalidade não for "ruim" ou "incorreta", mas apenas "inadequada para este caso de uso".
Uma questão importante com a abordagem "pull" é se a versão de dependência conta ou não como uma "unidade" ( de funcionalidade ) e, portanto, merece teste; ou se é apenas um detalhe de implementação "particular", que deve ser exercido apenas como parte dos testes reais de unidade ( de funcionalidade ). Eu diria: se a distinção entre as versões da dependência realmente conta como um recurso do seu aplicativo, faça o teste (por exemplo, verificando se a versão do Python é> = 3.x). Se não, então nãoadicione o teste (pois será quebradiço, pouco informativo e excessivamente restritivo); se você controlar a biblioteca, desça a rota "push". Se você não controla a biblioteca, basta usar a versão fornecida: se seus testes forem aprovados, não vale a pena se restringir; se eles não passarem, esse é o seu "prazo final" aí mesmo!
Existe outra abordagem, se você deseja desencorajar certos usos dos recursos de uma dependência (por exemplo, chamar determinadas funções que não funcionam bem com o restante do seu código), especialmente se você não controla a dependência: proibir seus padrões de codificação / desencoraje o uso desses recursos e adicione verificações ao seu linter.
Cada um deles será aplicável em diferentes circunstâncias.