Вопрос с собеседования · Java

В сервисе нужно сохранить момент оформления заказа и дату доставки, выбранную пользователем. Какие типы java.time возьмёшь и почему?

MiddleДата и время
Коротко

Момент оформления — Instant (в БД timestamptz, всегда UTC): событие произошло объективно, его сравнивают и сортируют глобально. Дата доставки — LocalDate: это не момент, а выбор человека «15 марта», и он не должен сдвигаться при смене зоны. Зону пользователя для показа хранят отдельно.

  • Ошибка: хранить дату доставки как момент в полночь — у пользователя в другой зоне она съедет на день
  • Время слота доставки — LocalTime плюс зона склада
  • Показ — конвертация Instant в зону пользователя на границе

А ещё Будущие события по местному времени (встреча в 10:00) хранят как LocalDateTime + ZoneId — правила зон меняются

Подробно

Разведи два вида времени — это и есть суть вопроса. Момент оформления заказа произошёл объективно, его надо уметь сравнивать и сортировать глобально, поэтому это Instant, в базе timestamptz, всегда в UTC. Дата доставки — не момент, а намерение человека: пользователь выбрал «пятнадцатое марта», и это должно остаться пятнадцатым марта независимо от того, из какого часового пояса он смотрит, поэтому LocalDate. Объясни, почему обратный выбор ломается: LocalDateTime без зоны не задаёт точку на оси времени — одно и то же значение соответствует разным моментам в разных поясах, поэтому хранить им время события нельзя. А если для даты доставки взять Instant, придётся выдумывать время суток и зону, и при переводе часов дата может сместиться на сутки. Добавь про зону: сам Instant её не хранит, поэтому если нужно показывать пользователю время в его поясе или считать «рабочий день по месту доставки», ZoneId сохраняют отдельным полем и применяют при отображении через ZonedDateTime. И упомяни, за что java.time вообще любят: типы неизменяемы и потокобезопасны, DateTimeFormatter можно держать в статическом поле — со старым SimpleDateFormat это давало плавающие баги.

Что хотят услышать

  • Разделение момента и календарной даты.
  • Хранение в БД.
  • Ошибка со сдвигом даты.

Частые ошибки

  • Хранить момент события в LocalDateTime без зоны.
  • Считать смещение и часовой пояс одним и тем же.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✗Оба значения — LocalDateTime без зоны, как они пришли из формы
  • ✗Оба — Instant: дату доставки хранить как полночь в UTC, так её удобно сравнивать с моментом заказа
  • ✓Момент оформления — Instant, дата доставки — LocalDate
  • ✗Момент — LocalDate, дата доставки — ZonedDateTime сервера

Что спросят дальше

  • Чем Duration отличается от Period и почему это важно при переходе на летнее время?
  • Что произойдёт с ZonedDateTime, если правила часового пояса изменятся?

Разбор темы

Связанные вопросы

Партнёр платформы

Разбор собеседования с sotto

После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.

Разбор собеседования