Создание объекта Java Date для полуночи: сегодня и завтра
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
LocalDateTime midnightToday = LocalDate.now().atStartOfDay();
LocalDateTime midnightTomorrow = midnightToday.plusDays(1);
Метод LocalDate.now()
используется для получения текущей даты, а atStartOfDay()
– для определения полуночи сегодняшнего дня. Вычисление времени полуночи следующего дня осуществляется путем добавления одного дня к переменной midnightToday
методом plusDays(1)
. Этот подход прост и точен, включая корректное учет часовых поясов.
Учет часовых поясов
Важно правильно учитывать часовые пояса при работе с датой и временем:
ZoneId myZone = ZoneId.of("America/New_York");
LocalDateTime midnightTodayAtMyZone = LocalDate.now(myZone).atStartOfDay();
LocalDateTime midnightTomorrowAtMyZone = midnightTodayAtMyZone.plusDays(1);
Работа с версиями Java 7 и ниже
В версиях Java до 8 включительно для этих целей можно использовать Calendar
, что несколько усложняет код:
Calendar midnightTodayLegacy = Calendar.getInstance();
midnightTodayLegacy.set(Calendar.HOUR_OF_DAY, 0);
midnightTodayLegacy.set(Calendar.MINUTE, 0);
midnightTodayLegacy.set(Calendar.SECOND, 0);
midnightTodayLegacy.set(Calendar.MILLISECOND, 0);
Calendar midnightTomorrowLegacy = (Calendar) midnightTodayLegacy.clone();
midnightTomorrowLegacy.add(Calendar.DAY_OF_MONTH, 1);
Использование класса Instant для работы с UTC
Для работы с временем в формате UTC и обеспечения совместимости в различных часовых поясах используйте класс Instant
:
Instant midnightTodayUTC = Instant.now().truncatedTo(ChronoUnit.DAYS);
Instant midnightTomorrowUTC = midnightTodayUTC.plus(1, ChronoUnit.DAYS);
Упрощаем код с использованием Apache Commons Lang
Если в вашем проекте используется Apache Commons Lang, рабочий процесс становится simpler благодаря классу DateUtils
:
Date midnightTodayCommons = DateUtils.truncate(new Date(), Calendar.DAY_OF_MONTH);
Date midnightTomorrowCommons = DateUtils.addDays(midnightTodayCommons, 1);
Визуализация
Подумаем о периоде от полуночи сегодняшнего дня до полуночи завтрашнего:
🌞 Сегодня:
Бодрствование начинается (🛌 -> 🏃) в 00:00 — 🕛
🌜 Сегодня вечером:
Время спать (🎉 -> 🛌) в 23:59 — 🕛 + 1 мин
🌞 Завтра:
Новый день начинается (🛌 -> 🏃) в 00:00 — 🕛 + 24 ч
Ассоциация течения времени от полуночи одного дня до полуночи следующего:
🏁 Старт: Полночь сегодня 🕛
🏃♂️ 24-часовой марафон
🏁 Финиш: Полночь завтра 🕛
В нашем случае дата и время представляют собой эстафету, где каждая полночь — это новый круг.
Будьте осторожны с точностью и возможными "подводными" камнями!
Работа с переходом на летнее время
Будьте внимательны при переходе на летнее время:
ZonedDateTime zonedMidnightToday = midnightTodayAtMyZone
.toLocalDate()
.atStartOfDay(myZone);
ZonedDateTime zonedMidnightTomorrow = zonedMidnightToday.plusDays(1);
Избегаем использования устаревших методов!
Не используйте класс DateMidnight
из Joda-Time, вместо этого выбирайте:
DateTime midnightTodayJoda = new DateTime().withTimeAtStartOfDay();
DateTime midnightTomorrowJoda = midnightTodayJoda.plusDays(1);
Высокосные секунды, високосные года, "скачущие" часы?
Будьте готовы к возникновению високосных секунд и других временных коррекций, которые могут повлиять на ваши расчеты.
Полезные материалы
- Java SE 8 Date and Time — официальный обзор API для работы с датой и временем в Java 8.
- Calendar (Java Platform SE 7 ) — описание класса Calendar.
- SimpleDateFormat (Java Platform SE 7 ) — особенности форматирования дат.
- java – Date parsing/formatting with TimeZone and SimpleDateFormat give different results around DST switch – Stack Overflow — обсуждение особенностей работы с часовыми поясами.