Получить дату без времени в Java

Получить дату без времени в Java

1. Вступление

В этом коротком руководстве мы покажем, как получитьDate без времени на Java.

Мы покажем, как это сделать до и после Java 8, поскольку после выпуска API нового времени в Java 8 все немного изменилось.

2. До Java 8

До Java 8 не было прямого способа получитьDate без времени, если только мы не использовали сторонние библиотеки, такие как Joda-time.

Это потому, чтоthe Date class in Java is a representation of a specific instant in time, expressed in milliseconds. Следовательно, это делает невозможным игнорировать время наDate.

В следующих разделах мы покажем некоторые общие обходные пути для решения этой проблемы.

2.1. ИспользуяCalendar

Один из наиболее распространенных способов получитьDate без времени - этоuse the Calendar class to set the time to zero. Делая это, мы получаем чистую дату с временем, установленным в начале дня.

Посмотрим на код:

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

Как мы видим, он возвращает полную дату с нулевым временем, ноwe can’t ignore the time.

Кроме того, чтобы убедиться, что в возвращаемыхDate не задано время, мы можем создать следующий тест:

@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. Использование форматтера

Другой способ сделать это -formatting a Date into a String without the time and then convert that String back to a Date. Поскольку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

Опять же, мы можем использовать тест, как и раньше, чтобы убедиться, что в возвращаемыхDate нет времени.

3. Использование Java 8

С выпуском нового API времени в Java 8 появился более простой способ получить дату без времени. Одна из новых функций этого нового API заключается в том, что есть несколько классов для работы с датами со временем или без него или даже для работы только со временем.

В этой статье мы сосредоточимся на классеLocalDate, который представляет именно то, что нам нужно, дату без времени.

Давайте посмотрим на это на следующем примере:

public static LocalDate getLocalDate() {
    return LocalDate.now();
}

Этот метод возвращает объектLocalDate с таким представлением даты:

2018-06-23

Как мы видим, он возвращает только датуthe time is completely ignored.

Опять же, давайте проверим его, как и раньше, чтобы убедиться, что этот метод работает должным образом:

@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. Заключение

В этой статье мы показали, как получитьDate без времени на Java. Сначала мы показали, как это сделать до Java 8, а также с использованием Java 8.

Как мы могли видеть в примерах, реализованных в статье, с использованиемJava 8 should be always the preferred option, поскольку он имеет специальное представление для работы с датами без времени.

Как всегда, доступен полный исходный код примеровover on GitHub.