Перейти к основному содержимому

Как получить все даты между двумя датами?

· 3 мин. чтения

1. Обзор

Новый Time API, представленный в Java 8, позволяет обрабатывать дату и время без использования внешних библиотек.

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

2. Использование Java 7

В Java 7 один из способов вычислить это — использовать экземпляр Calendar .

Во-первых, мы получим даты начала и окончания без учета времени . Затем мы будем перебирать их и добавлять один день в каждой итерации, используя метод добавления и поле Calendar.Date , пока не будет достигнута дата окончания.

Вот код, демонстрирующий это — с использованием экземпляра Calendar :

public static List getDatesBetweenUsingJava7(Date startDate, Date endDate) {
List datesInRange = new ArrayList<>();
Calendar calendar = getCalendarWithoutTime(startDate);
Calendar endCalendar = getCalendarWithoutTime(endDate);

while (calendar.before(endCalendar)) {
Date result = calendar.getTime();
datesInRange.add(result);
calendar.add(Calendar.DATE, 1);
}

return datesInRange;
}

private static Calendar getCalendarWithoutTime(Date date) {
Calendar calendar = new GregorianCalendar();
calendar.setTime(date);
calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar;
}

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

В Java 8 теперь мы можем создавать непрерывный бесконечный поток дат и брать только соответствующую часть. К сожалению, нет способа завершить бесконечный поток при совпадении предиката — вот почему нам нужно вычислить количество дней между этими двумя днями, а затем просто limit() для потока:

public static List<LocalDate> getDatesBetweenUsingJava8(
LocalDate startDate, LocalDate endDate) {

long numOfDaysBetween = ChronoUnit.DAYS.between(startDate, endDate);
return IntStream.iterate(0, i -> i + 1)
.limit(numOfDaysBetween)
.mapToObj(i -> startDate.plusDays(i))
.collect(Collectors.toList());
}

Обратите внимание, как, во-первых, мы можем получить разницу в днях между двумя датами, используя функцию between , связанную с константой DAYS перечисления ChronoUnit .

Затем мы создаем поток целых чисел, представляющий количество дней с даты начала. На следующем шаге мы преобразуем наши целые числа в объекты LocalDate , используя API plusDays() .

Наконец, мы собираем все в экземпляр списка.

4. Использование Java 9

Наконец, Java 9 предоставляет специальные методы для вычисления этого:

public static List<LocalDate> getDatesBetweenUsingJava9(
LocalDate startDate, LocalDate endDate) {

return startDate.datesUntil(endDate)
.collect(Collectors.toList());
}

Мы можем получить даты между двумя датами с помощью одного вызова метода, используя специальный метод dateUntil класса LocalDate . DatesUntill возвращает последовательно упорядоченный поток дат, начиная с объекта даты, метод которого вызывается, до даты, указанной в качестве аргумента метода.

5. Вывод

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

Мы обсудили, как Time API, представленный в выпуске Java 8, упростил выполнение операций над литералами даты, а в Java 9 это можно сделать, просто вызвав dateUntil.

И, как всегда, фрагменты кода можно найти на GitHub .