Дата и время в Java: java.time API и текущая дата - Вопросы
Всего: 6 вопросов
1. Что такое Java Date Time API (java.time) и какие классы в него входят?
Что такое 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?
Как получить текущую дату и время в 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)?
Почему 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, 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?
Чем 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 и обратно?
Как преобразовать 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 напрямую.