Дата и время в Java: java.time API и текущая дата - Вопросы

Всего: 6 вопросов

1. 

Что такое Java Date Time API (java.time) и какие классы в него входят?

Java Date Time API — пакет java.time (JSR-310), стандартная библиотека для работы с датой и временем, добавленная в Java 8 на замену java.util.Date и java.util.Calendar.

Основные классы:

  • LocalDate — дата без времени (2026-10-17);
  • LocalTime — время суток (14:35:07);
  • LocalDateTime — дата и время без часового пояса;
  • ZonedDateTime — дата и время в конкретном поясе (Europe/Moscow);
  • Instant — момент на шкале UTC;
  • Period и Duration — промежутки в годах/месяцах/днях и в секундах/наносекундах.

Все эти классы неизменяемы и потокобезопасны. Точки на шкале времени реализуют интерфейс java.time.temporal.Temporal, промежутки — java.time.temporal.TemporalAmount.

2. 

Как получить текущую дату и время в Java?

Статическим методом now() нужного класса из java.time:

  • LocalDate.now() — только дата: 2026-10-17;
  • LocalTime.now() — только время: 14:35:07.123456;
  • LocalDateTime.now() — дата и время: 2026-10-17T14:35:07.123456;
  • ZonedDateTime.now() — дата и время с поясом JVM: 2026-10-17T14:35:07.123456+03:00[Europe/Moscow];
  • Instant.now() — текущий момент, печатается в UTC: 2026-10-17T11:35:07.123456Z.

Точность дробной части зависит от версии Java: в Java 8 — миллисекунды, начиная с Java 9 — обычно микросекунды. Для вывода в формате dd.MM.yyyy используют LocalDate.now().format(DateTimeFormatter.ofPattern("dd.MM.yyyy")).

3. 

Почему LocalDateTime.now() на сервере может показывать другое время, чем на вашем компьютере, и зачем нужны now(ZoneId) и now(Clock)?

Метод now() без аргументов берёт часовой пояс JVM по умолчанию (ZoneId.systemDefault()), а он зависит от настроек ОС. Если сервер работает в UTC, а вы в Москве, разница составит 3 часа, а около полуночи будет отличаться даже дата.

  • now(ZoneId) возвращает время в явно указанном поясе: LocalDateTime.now(ZoneId.of("Europe/Moscow")).
  • now(Clock) берёт время из объекта Clock. В рабочем коде передают Clock.systemDefaultZone(), а в unit-тесте — Clock.fixed(Instant.parse("2024-02-29T10:00:00Z"), ZoneOffset.UTC): тогда LocalDate.now(clock) всегда возвращает 2024-02-29, и тест не зависит от дня запуска.

Другие варианты — задать JVM параметр -Duser.timezone=Europe/Moscow или хранить моменты в Instant и переводить в нужную зону только при выводе.

4. 

Чем отличаются LocalDateTime, ZonedDateTime и Instant? Хранит ли Instant часовой пояс?

  • LocalDateTime — дата и время «как на настенных часах» без пояса: 2026-10-17T14:35:07. Подходит для времени встречи в одном городе, времени в чеке.
  • ZonedDateTime — дата, время и часовой пояс: 2026-10-17T14:35:07+03:00[Europe/Moscow]. Подходит для рейсов, созвонов между странами, перехода на летнее время.
  • Instant — секунды и наносекунды от 1970-01-01T00:00:00Z, точный момент времени. Подходит для меток времени в логах, БД, между сервисами.

Нет, Instant часовой пояс не хранит: это просто момент на шкале UTC, поэтому toString() всегда печатает его в UTC (суффикс Z). Часовой пояс есть только у ZonedDateTime (зона вида Europe/Moscow) и OffsetDateTime (смещение вида +03:00). Чтобы получить местное время из Instant, нужно указать зону: instant.atZone(ZoneId.of("Europe/Moscow")).

5. 

Чем java.time лучше java.util.Date и java.util.Calendar?

  • Неизменяемость. Date и Calendar меняются методами setTime(), set(), add(); в java.time методы вроде plusDays() возвращают новый объект.
  • Потокобезопасность. Старые классы и SimpleDateFormat не потокобезопасны; классы java.time, включая DateTimeFormatter, потокобезопасны.
  • Нумерация. В старом API месяцы идут с 0, а в new Date(y, m, d) год отсчитывается от 1900: new Date(2024, 1, 15) — это 15 февраля 3924 года. В java.time месяцы с 1 и есть перечисление Month: LocalDate.of(2024, 2, 15).
  • Проверка значений. Calendar молча переносит 29.02.2023 на 01.03.2023, а LocalDate.of(2023, 2, 29) бросает DateTimeException.
  • Разделение понятий. Date одновременно и дата, и время, и момент; в java.time отдельный класс на каждую задачу.
6. 

Как преобразовать java.util.Date в LocalDate или LocalDateTime и обратно?

Через Instant и обязательно с указанием часового пояса, потому что Date — это момент времени (миллисекунды от эпохи), а LocalDate/LocalDateTime пояса не имеют:

  • Date → Instant: date.toInstant(); обратно — Date.from(instant);
  • Date → LocalDateTime: date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime() (или .toLocalDate() для даты);
  • LocalDateTime → Date: Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
  • GregorianCalendar ↔ ZonedDateTime: calendar.toZonedDateTime() / GregorianCalendar.from(zdt);
  • java.sql.Date ↔ LocalDate: sqlDate.toLocalDate() / java.sql.Date.valueOf(localDate).

Пример: new Date(0L) в поясе Europe/Moscow даёт 1970-01-01T03:00. Конвертация нужна только на границе со старым кодом: JDBC 4.2 и Hibernate 5+ работают с LocalDate, LocalDateTime и Instant напрямую.

Страница 1 из 1