Как откатить дату на час назад в Java: методы и практика

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Если вам нужно уменьшить время в объекте Date на один час, воспользуйтесь классом Calendar:

Java
Скопировать код
Date now = new Date(); // текущие дата и время
Calendar cal = Calendar.getInstance(); // создаём экземпляр Calendar
cal.setTime(now); // устанавливаем в Calendar текущее время
cal.add(Calendar.HOUR_OF_DAY, -1); // вычитаем один час
Date oneHourBack = cal.getTime(); // получаем изменённое время

System.out.println(oneHourBack); // выводим новое время

Мы уменьшаем время, используя константу Calendar.HOUR_OF_DAY и метод add с аргументом -1.

Кинга Идем в IT: пошаговый план для смены профессии

Java 8 и новее: Современный подход

java.time: Классы LocalDateTime и ZonedDateTime

В Java 8 добавили новые удобные классы для работы с датами в пакете java.time:

Java
Скопировать код
// Создаём объект LocalDateTime
LocalDateTime now = LocalDateTime.now(); // текущее время
LocalDateTime oneHourBack = now.minusHours(1); // вычитаем один час

// Создаём объект ZonedDateTime
ZonedDateTime zonedNow = ZonedDateTime.now(); // текущее время с учётом временных зон
ZonedDateTime zonedOneHourBack = zonedNow.minusHours(1); // вычитаем один час

ZonedDateTime автоматически учитывает переходы на летнее/зимнее время и разницу во временных зонах.

Использование Instant: Конкретность и ясность

Instant создан для работы с точными временными метками:

Java
Скопировать код
Instant instantNow = Instant.now(); // текущая временная метка в UTC
Instant instantOneHourBack = instantNow.minus(1, ChronoUnit.HOURS); // откатываемся на час назад

Instant всегда работает в UTC/GMT.

Использование TimeUnit для легкости расчётов

TimeUnit облегчает работу с временными единицами измерения:

Java
Скопировать код
long oneHourInMilliseconds = TimeUnit.HOURS.toMillis(1); // переводим час в миллисекунды
Date newDate = new Date(System.currentTimeMillis() – oneHourInMilliseconds); // уменьшаем текущее время на час

TimeUnit избавляет от использования "магических чисел" в коде.

Визуализация

Вот пример простой операции со временем в Java:

Java
Скопировать код
// Текущее время: 14:00 🕑
Date currentTime = new Date(); // зафиксировали начальное время

Совершаем путешествие в прошлое:

Java
Скопировать код
// Корректируем время
currentTime.setTime(currentTime.getTime() – 3600 * 1000); // уменьшаем время на час

И вот что получается:

Markdown
Скопировать код
До:     14:00 🕑
После:  13:00 🕒

Как будто мы повернули стрелки старинных часов назад.

Версии для новых и старых решений

Преобразование между java.util.Date и java.time

Пример кода для работы с новым и старым API:

Java
Скопировать код
Instant dateToInstant = new Date().toInstant(); // преобразуем Date в Instant
Date instantToDate = Date.from(Instant.now()); // преобразуем Instant обратно в Date

Так можно раскрашивать и обратно отбеливать фотографии.

Joda-Time: Инструментарий для работы с датами

До появления java.time разработчики часто использовали библиотеку Joda-Time:

Java
Скопировать код
org.joda.time.LocalDateTime jodaNow = org.joda.time.LocalDateTime.now();
org.joda.time.LocalDateTime jodaOneHourBack = jodaNow.minusHours(1);

Сейчас Joda-Time активно применяется в поддержке старых проектов.

Работа с базами данных: Совместимость с JDBC

С 4.2 версии драйверы JDBC полностью поддерживают java.time:

Java
Скопировать код
// Устанавливаем параметры для SQL-запросов с использованием java.time
PreparedStatement st = con.prepareStatement("SELECT * FROM events WHERE event_time > ?");
st.setObject(1, LocalDateTime.now()); // работаем с датой и временем через базу данных

Временные зоны и DST: учтём особенности

Нельзя забывать о временных зонах и переходе на летнее/зимнее время:

Java
Скопировать код
ZonedDateTime zonedNow = ZonedDateTime.now(ZoneId.of("America/New_York")); // текущее время в Нью-Йорке, США
ZonedDateTime zonedOneHourBack = zonedNow.minusHours(1); // дарим жителям города дополнительный час отдыха

Обязательно учитывайте эти моменты при тестировании.

Полезные материалы

  1. Путь: Дата и время (Java™ Tutorials) — подробное руководство по API Java для работы с датами и временем.
  2. Calendar (Java Platform SE 8) — описание методов add и roll в API Calendar.
  3. SimpleDateFormat (Java Platform SE 8) — как форматировать дату при помощи SimpleDateFormat.
  4. ZonedDateTime (Java Platform SE 8) — инструкция по использованию ZonedDateTime.
  5. Всё о java.util.Date | Блог о программировании от Jon Skeet — обзор работы с датами в Java с практическими советами.
  6. Joda-Time – Начало — введение в Joda-Time, альтернативу стандартным средствам Java по работе с датой и временем.