Один из способов думать об этом - то, что вы подразумеваете под временем / датой ? Компьютеры не знают, что это за понятия: они должны быть каким-то образом запрограммированы. Распространено представлять время в формате UNIX «секунд с начала эпохи», и обычно вводить определенное значение в программу с помощью вызовов ОС. Однако, независимо от того, насколько распространено это использование, важно помнить, что это не «фактическое» время: это просто логическое представление.
Как уже отмечали другие, если вы установили «крайний срок», используя этот механизм, тривиально кормить в другое время и нарушать этот «крайний срок». То же самое касается более сложных механизмов, таких как запрос NTP-сервера (даже через «безопасное» соединение, поскольку мы можем заменять наши собственные сертификаты, центры сертификации или даже исправлять криптографические библиотеки). Сначала может показаться, что такие люди виноваты в работе вокруг вашего механизма, но может случиться так, что это делается автоматически и по уважительным причинам . Например, неплохо иметь воспроизводимые сборки , и инструменты, которые могут помочь в этом, могут автоматически сбрасывать / перехватывать такие недетерминированные системные вызовы. libfaketime делает именно это,устанавливает временные метки всех файлов, функция записи / воспроизведения1970-01-01 00:00:01
Qemu подделывает все аппаратное взаимодействие и т. д.
Это похоже на закон Гудхарта : если вы заставляете поведение программы зависеть от логического времени, то логическое время перестает быть хорошей мерой «фактического» времени. Другими словами, люди обычно не будут связываться с системными часами, но они будут, если вы дадите им причину.
Существуют и другие логические представления времени: одним из них является версия программного обеспечения (либо ваше приложение, либо некоторая зависимость). Это более желательное представление для «крайнего срока», чем, например, для времени UNIX, так как оно более специфично для того, что вас волнует (изменение наборов функций / API), и, следовательно, с меньшей вероятностью нарушит ортогональные задачи (например, возиться со временем UNIX до работа в установленные сроки может привести к повреждению файлов журналов, заданий cron, кешей и т. д.).
Как уже говорили другие, если вы управляете библиотекой и хотите «подтолкнуть» это изменение, вы можете нажать новую версию, которая устарела, и вызвать новые предупреждения, чтобы помочь пользователям найти и обновить их использование), а затем другую новую версию, которая удаляет Особенности полностью. Вы можете опубликовать их сразу после друг друга, если хотите, поскольку (опять же) версии являются просто логическим представлением времени, они не должны быть связаны с «фактическим» временем. Семантическая версия может помочь здесь.
Альтернативная модель - «вытянуть» изменения. Это похоже на ваш «план Б»: добавьте тест в приложение-потребитель, которое проверяет, что версия этой зависимости, по крайней мере, является новым значением. Как обычно, красный / зеленый / рефакторинг для распространения этого изменения через кодовую базу. Это может быть более подходящим, если функциональность не является «плохой» или «неправильной», а просто «плохо подходит для этого варианта использования».
Важный вопрос с подходом «pull» заключается в том, считается ли версия зависимости «единицей» ( функциональности ) и, следовательно, заслуживает тестирования; или это просто «частная» деталь реализации, которая должна выполняться только как часть реальных модульных ( функциональных ) тестов. Я бы сказал: если различие между версиями зависимости действительно считается особенностью вашего приложения, тогда проведите тест (например, проверяя, что версия Python>> 3.x). Если нет, то недобавить тест (поскольку он будет хрупким, неинформативным и чрезмерно ограничительным); если вы управляете библиотекой, тогда идите по «push» маршруту. Если вы не управляете библиотекой, просто используйте ту версию, которая вам предоставлена: если ваши тесты пройдут, ограничивать себя не стоит; если они не пройдут, значит, это ваш «крайний срок»!
Существует другой подход, если вы хотите препятствовать определенному использованию функций зависимостей (например, вызывать определенные функции, которые плохо работают с остальным кодом), особенно если вы не контролируете зависимость: запретите свои стандарты кодирования / не поощряйте использование этих функций и добавляйте проверки для их линтера.
Каждый из них будет применим в разных обстоятельствах.