Как стать автором
Обновить

Комментарии 13

Можно просто не использовать напрямую работу с датой и временем а вынести в отдельный сервис . Потом можно менять реализацию сколько захочется. В тестах мокать и выставлять любое время. И не нужно никаких радикальных ограничений на code-style. Все просто.

А что помешает разработчику вызвать LocalDateTime.now()? И здесь речь даже не про злой умысел/раздолбайство, а просто про нового человека в команде, который ещё слабо ориентируется в кодовой базе?
Простой вариант не жизнеспособен на большом отрезке времени, когда команда может полностью обновиться или продукт уйдёт на поддержку совершенно другой команде.

так у вас то тоже ничего не запрещает разрабу вызвать  LocalDateTime.now()? кроме стайлчека..добавить к утилитному классу рестрикт и все.

В предлагаемом мною варианте разработчик получит ошибку компиляции при попытке использовать now(). Checkstyle позволяет настраивать сообщения об ошибках, и туда можно прокинуть, например, ссылку на эту статью или на внутреннюю wiki, где будет объясняться концепция.

Попытки обойти это ограничение должны отлавливаться уже на этапе код ревью.

Например, кодстайлчекер?

В моем текущем проекте уже лет 5 никто руками даты не создает. Несколько десятков программистов колбасят - это пять команд, люди периодически приходят и уходят. И все хорошо.

Если у вас нет нормального code review на проекте, вас ничего не спасет от "творчества" таких разработчиков. Ну забанили Вы слово now, что дальше? Есть еще миллион и один способ как угробить проект, если нет нормального контроля качества кода. Знаете что будет в реальной жизни? Отдадут проект на поддержку другой команде и через непродолжительное время найдется разработчик который посчитает написанное Вами правило глупым и просто отключит его. Вот и вся жизнеспособность на большом отрезке времени.

Не совсем понятно, чем Clock лучше проставления ZoneOffset/ZoneId ?

Мне кажется, использование Clock не спасёт от проставления ZoneId, но могу ошибаться.

А сам Clock полезен для тестирования вещей, завязанных на время. Можно в тестах замокать Clock и заставить его возвращать фиксированное значение, либо некую последовательность, например, текущее время, а потом внезапный прыжок на год вперёд, например.

Я бы рекомендовал не использовать LocalDateTime если для этого нет специальных причин. Очень велик шанс потерять правильную таймзону и получить неправильное время

OffsetDateTime или лучше ZonedDateTime. Так вы сможете перекидывать даты повсюду (другие сервисы, фронт, бд и т.п.) без рисков и без знания, на какой же таймзоне работает ваш сервер.

Пулл реквесты в демо-проект приветствуются. Можно перейти на OffsetDateTime

Согласен, но плюсануть технически не могу ))

Считаю, что Clock.systemUTC() (или UTC zoneId) в большинстве случаев не должен использоваться для LocalXXX. LocalXXX классы не просто так называются 'local' - они должны использоваться с часами или ZoneId пользователя, страны или региона (если это подразумевается вашей бизнес логикой). Какой вам смысл, находясь в Сахалине, знать что по Лондону уже наступил понедельник?

private LocalDateTime createdAt;

Это грубейшая ошибка, которая говорит о том, что вы не понимаете, как правильно использовать Java Time API, и даже не читали официальную документацию. А в ней вполне конкретно написано: "LocalDateTime is a description of the date, as used for birthdays, combined with the local time as seen on a wall clock. It cannot represent an instant on the time-line without additional information such as an offset or time-zone."

В вашем случае должно быть:

private ZonedDateTime createdAt;

Но тогда большая часть страданий и "полезных советов" из статьи становится неактуальной.

Покажите код, который запишет ваш пример с ZonedDateTime в БД PostgreSQL, а там посмотрим, в чём конкретно я не прав. Попутно можете почитать https://jdbc.postgresql.org/documentation/head/java8-date-time.html и https://docs.oracle.com/javase/8/docs/api/java/time/ZonedDateTime.html

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации