Переход на строгую модель работы с датой и временем через js-joda в
зрелых проектах почти никогда не выполняется одномоментно. Причина
заключается в высокой связности временной логики с бизнес-правилами,
хранилищами данных, API-границами и сторонними библиотеками,
использующими стандартный Date. Поэтому основной подход
опирается на поэтапную изоляцию и контролируемое расширение зоны
использования новой модели времени.
Ключевая цель постепенной миграции — исключить «протекание» разных
представлений времени по системе и добиться того, чтобы каждая граница
ответственности имела однозначный формат: либо legacy Date,
либо объекты js-joda.
Первый шаг связан не с заменой кода, а с формализацией границ, где происходят переходы между моделями времени.
Типовые границы:
На практике именно границы становятся точками «перевода»:
Важно закрепить принцип: внутри домена существует только одна модель времени. Для постепенной миграции вводится временное сосуществование, но строго ограниченное слоями адаптации.
Наиболее устойчивой стратегией является создание отдельного модуля-адаптера, инкапсулирующего работу с js-joda.
Адаптер выполняет функции:
Date → LocalDate,
Instant, ZonedDateTimeDate или строкуПример логической структуры:
/time
/adapter
fromLegacy.ts
toLegacy.ts
/domain
dateModel.ts
/format
formatters.ts
Преимущество данного подхода заключается в том, что изменение библиотечного решения или расширение функциональности затрагивает только один слой.
При интеграции с существующим кодом часто возникает риск смешивания моделей времени. Для предотвращения этого используется антикоррупционный слой (Anti-Corruption Layer).
Он выполняет две функции:
DateВ этом слое запрещается:
Date в бизнес-логикуРезультат: домен становится независимым от внешних временных представлений.
Полная миграция на js-joda осуществляется не горизонтально, а вертикальными срезами системы.
Подход:
DateПреимущество заключается в снижении риска: изменения локализуются и не распространяются на всю систему одновременно.
На промежуточном этапе неизбежно сосуществование двух представлений:
Date (внешние API, старые модули)Для управления этим состоянием вводятся строгие правила:
Особое внимание уделяется сериализации. Часто ошибки возникают именно при неявном преобразовании через JSON.
Основная сложность миграции связана с тем, что js-joda объекты не
сериализуются стандартным JSON.stringify.
Поэтому вводятся явные стратегии:
Типовой подход:
"2026-05-25T10:15:00Z"Instant, LocalDateTime,
ZonedDateTimeЭто исключает скрытые преобразования и снижает вероятность расхождений времени между сервисами.
После стабилизации адаптеров начинается перенос вычислительной логики времени.
Зоны миграции:
Пример типичной замены:
Было:
const diff = dateA.getTime() - dateB.getTime();
Становится:
const diff = Duration.between(instantA, instantB).toMillis();
Использование js-joda позволяет устранить неоднозначности, связанные
с летним временем, локальными зонами и мутирующими объектами
Date.
Особое внимание требуется при работе с базами данных.
Типовые проблемы:
Стратегии миграции:
В большинстве случаев предпочтительна стратегия «не трогать базу, менять только представление в коде».
При миграции выявляются скрытые проблемы:
js-joda предоставляет строгие типы, которые позволяют явно различать:
LocalDate — дата без времениInstant — момент в UTCZonedDateTime — момент с зонойLocalDateTime — локальное время без зоныРазделение этих типов устраняет класс ошибок, связанных с неявной
интерпретацией Date.
При постепенном переходе тесты выполняют роль стабилизатора поведения.
Основные стратегии:
Часто используется двойной расчёт:
Это позволяет безопасно переключать функциональность.
На этапе миграции API не изменяется, но внутренние структуры меняются.
Для этого вводятся:
Особое значение имеет контроль мест, где происходит автоматическое приведение типов, так как именно там чаще всего возникают скрытые дефекты.
Наиболее опасный паттерн — смешивание Date и js-joda в
одной функции.
Типичный антипаттерн:
Date.getTime()Duration или PeriodПри миграции такие места переписываются полностью, без частичной адаптации, поскольку смешанная модель нарушает предсказуемость поведения времени.
Финальная стадия постепенной миграции заключается в закреплении единой модели времени внутри системы.
В этот момент:
Date остаётся только на границе внешних интеграцийДоменные сущности перестают зависеть от внешнего представления времени и оперируют строго типизированными объектами.
В процессе перехода неизбежно возникает временный технический долг:
Для его контроля применяется:
DateСтруктурированный подход предотвращает накопление хаотичных преобразований и снижает риск регрессий.