1. Введение
В этом коротком руководстве мы покажем, как получить дату
без времени в Java.
Мы покажем, как это сделать до и после Java 8, поскольку после выпуска нового API времени в Java 8 все стало немного иначе.
2. До Java 8
До Java 8 не было прямого способа получить Date
без времени, если только мы не использовали сторонние библиотеки, такие как Joda-time.
Это связано с тем, что класс Date
в Java является представлением определенного момента времени, выраженного в миллисекундах . Следовательно, это делает невозможным игнорирование времени в Date
.
В следующих разделах мы покажем некоторые общие обходные пути для решения этой проблемы.
2.1. Использование календаря
Один из наиболее распространенных способов получить Date
без времени — использовать класс Calendar
, чтобы установить время равным нулю . Делая это, мы получаем чистую дату со временем, установленным в начале дня.
Давайте посмотрим на это в коде:
public static Date getDateWithoutTimeUsingCalendar() {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime();
}
Если мы вызовем этот метод, мы получим такую дату:
Sat Jun 23 00:00:00 CEST 2018
Как мы видим, он возвращает полную дату с нулевым временем, но мы не можем игнорировать время .
Кроме того, чтобы убедиться, что в возвращаемой дате
не установлено время , мы можем создать следующий тест:
@Test
public void whenGettingDateWithoutTimeUsingCalendar_thenReturnDateWithoutTime() {
Date dateWithoutTime = DateWithoutTime.getDateWithoutTimeUsingCalendar();
Calendar calendar = Calendar.getInstance();
calendar.setTime(dateWithoutTime);
int day = calendar.get(Calendar.DAY_OF_MONTH);
calendar.setTimeInMillis(dateWithoutTime.getTime() + MILLISECONDS_PER_DAY - 1);
assertEquals(day, calendar.get(Calendar.DAY_OF_MONTH));
calendar.setTimeInMillis(dateWithoutTime.getTime() + MILLISECONDS_PER_DAY);
assertNotEquals(day, calendar.get(Calendar.DAY_OF_MONTH));
}
Как мы видим, когда мы добавляем к дате миллисекунды дня минус один, мы по-прежнему получаем тот же день, но когда мы добавляем полный день, мы получаем следующий день.
2.2. Использование форматирования
Другой способ сделать это - отформатировать Date
в String
без времени, а затем преобразовать эту String
обратно в Date
. Поскольку строка
была отформатирована без указания времени, преобразованная дата
будет иметь нулевое время.
Давайте реализуем это, чтобы увидеть, как это работает:
public static Date getDateWithoutTimeUsingFormat()
throws ParseException {
SimpleDateFormat formatter = new SimpleDateFormat(
"dd/MM/yyyy");
return formatter.parse(formatter.format(new Date()));
}
Эта реализация возвращает то же самое, что и метод, показанный в предыдущем разделе:
Sat Jun 23 00:00:00 CEST 2018
Опять же, мы можем использовать тест, как мы делали раньше, чтобы убедиться, что в возвращаемой дате нет времени.
3. Использование Java 8
С выпуском нового API времени в Java 8 появился более простой способ получить дату без времени. Одна из новых функций, которую принес этот новый API, заключается в том, что есть несколько классов для работы с датами со временем или без него или даже для работы только со временем.
Ради этой статьи мы сосредоточимся на классе LocalDate
, который представляет именно то, что нам нужно, дату без времени.
Давайте посмотрим на этот пример:
public static LocalDate getLocalDate() {
return LocalDate.now();
}
Этот метод возвращает объект LocalDate
с этим представлением даты:
2018-06-23
Как мы видим, он возвращает просто дату, время полностью игнорируется .
Опять же, давайте проверим его, как и раньше, чтобы убедиться, что этот метод работает должным образом:
@Test
public void whenGettingLocalDate_thenReturnDateWithoutTime() {
LocalDate localDate = DateWithoutTime.getLocalDate();
long millisLocalDate = localDate
.atStartOfDay()
.toInstant(OffsetDateTime
.now()
.getOffset())
.toEpochMilli();
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(
millisLocalDate + MILLISECONDS_PER_DAY - 1);
assertEquals(
localDate.getDayOfMonth(),
calendar.get(Calendar.DAY_OF_MONTH));
calendar.setTimeInMillis(millisLocalDate + MILLISECONDS_PER_DAY);
assertNotEquals(
localDate.getDayOfMonth(),
calendar.get(Calendar.DAY_OF_MONTH));
}
4. Вывод
В этой статье мы показали, как получить дату
без времени в Java. Сначала мы показали, как это сделать до Java 8, а также с использованием Java 8.
Как мы могли видеть в примерах, реализованных в статье, использование Java 8 всегда должно быть предпочтительным вариантом , поскольку у него есть специфическое представление для работы с датами без времени.
Как всегда, полный исходный код примеров доступен на GitHub .