Uma maneira de pensar sobre isso é o que você quer dizer com hora / data ? Os computadores não sabem o que são esses conceitos: eles precisam ser programados de alguma forma. É bastante comum representar vezes no formato UNIX de "segundos desde a época", e é comum alimentar um determinado valor em um programa por meio de chamadas do sistema operacional. No entanto, não importa quão comum seja esse uso, é importante ter em mente que não é o tempo "real": é apenas uma representação lógica.
Como outros apontaram, se você fez um "prazo" usando este mecanismo, é trivial para alimentar em um horário diferente e quebrar esse "prazo". O mesmo vale para mecanismos mais elaborados, como perguntar a um servidor NTP (mesmo através de uma conexão "segura", já que podemos substituir nossos próprios certificados, autoridades de certificação ou até mesmo corrigir as bibliotecas de criptografia). A princípio, pode parecer que esses indivíduos são culpados por trabalhar em torno de seu mecanismo, mas pode ser o caso que é feito automaticamente e por boas razões . Por exemplo, é uma boa ideia ter compilações reproduzíveis e ferramentas para ajudar a redefinir / interceptar automaticamente essas chamadas de sistema não determinísticas. libfaketime faz exatamente isso, Nix define todos timestamps do arquivo para 1970-01-01 00:00:01
, o recurso de gravação / reprodução do Qemu falsifica toda a interação de hardware, etc. .
Isto é similar a Lei de Goodhart : se você fizer o comportamento de um programa depender do tempo lógico, então o o tempo lógico deixa de ser uma boa medida do tempo "real". Em outras palavras, as pessoas geralmente não vão mexer no relógio do sistema, mas sim se você der um motivo para elas.
Existem outras representações lógicas do tempo: uma delas é a versão do software (seu aplicativo ou alguma dependência). Esta é uma representação mais desejável para um "prazo" do que, e. Tempo no UNIX, já que é mais específico do que você gosta (alterar conjuntos de recursos / APIs) e, portanto, menos propenso a atropelar preocupações ortogonais (por exemplo, mexer com o tempo do UNIX para trabalhar no prazo pode acabar quebrando arquivos de log , caches, etc.).
Como outros já disseram, se você controlar a biblioteca e quiser "empurrar" essa alteração, poderá enviar uma nova versão que deprecia os recursos (causando avisos, ajudar os consumidores a encontrar e atualizar seu uso) e, em seguida, outra nova versão que remove completamente os recursos. Você poderia publicá-las imediatamente uma após a outra, se quiser, já que (novamente) as versões são apenas uma representação lógica do tempo, elas não precisam estar relacionadas ao tempo "real". Versões semânticas podem ajudar aqui.
O modelo alternativo é "puxar" a mudança. Isso é como seu "plano B": inclua um teste no aplicativo consumidor, que verifica se a versão dessa dependência é pelo menos o novo valor. Como de costume, red / green / refactor para propagar essa mudança através da base de código. Isso pode ser mais apropriado se a funcionalidade não for "ruim" ou "errada", mas apenas "um ajuste inadequado 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" ( da funcionalidade ) e, portanto, merece testes; ou se é apenas um detalhe de implementação "particular", que deve ser exercido apenas como parte da unidade real ( da funcionalidade ) testes. Eu diria: se a distinção entre as versões da dependência realmente contar 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ão adicione o teste (pois ele será frágil, não-informativo e excessivamente restritivo); se você controlar a biblioteca, desça a rota "push". Se você não controla a biblioteca, basta usar qualquer versão que seja fornecida: se seus testes forem aprovados, não vale a pena se restringir; se eles não passarem, então esse é o seu "prazo" ali mesmo!
Existe outra abordagem, se você quiser desencorajar certos usos dos recursos de uma dependência (por exemplo, chamar certas funções que não funcionam bem com o resto do seu código), especialmente se você não controlar a dependência: os padrões de codificação proíbem / desencorajam o uso desses recursos e adicionam verificações para eles no seu linter.
Cada um deles será aplicável em diferentes circunstâncias.