как получить список дат между двумя датами в Java - PullRequest
59 голосов
/ 22 апреля 2010

Я хочу список дат между начальной и конечной датой.

Результатом должен быть список всех дат, включая даты начала и окончания.

Ответы [ 21 ]

46 голосов
/ 22 апреля 2010

Еще в 2010 году я предложил использовать для этого Joda-Time .

Обратите внимание, что Joda-Time сейчас находится в режиме обслуживания.Начиная с версии 1.8 (2014), вы должны использовать java.time.

Добавлять один день за раз до достижения конечной даты:

int days = Days.daysBetween(startDate, endDate).getDays();
List<LocalDate> dates = new ArrayList<LocalDate>(days);  // Set initial capacity to `days`.
for (int i=0; i < days; i++) {
    LocalDate d = startDate.withFieldAdded(DurationFieldType.days(), i);
    dates.add(d);
}

Это не будет слишком сложночтобы реализовать и собственный итератор, это было бы еще лучше.

38 голосов
/ 29 мая 2014

Пакет java.time

Если вы используете Java 8 , есть более чистый подход. Новый java.time пакет в Java 8 включает функции API Joda-Time .

Ваше требование может быть решено с помощью приведенного ниже кода:

String s = "2014-05-01";
String e = "2014-05-10";
LocalDate start = LocalDate.parse(s);
LocalDate end = LocalDate.parse(e);
List<LocalDate> totalDates = new ArrayList<>();
while (!start.isAfter(end)) {
    totalDates.add(start);
    start = start.plusDays(1);
}
37 голосов
/ 24 мая 2010

Получите количество дней между датами включительно.

public static List<Date> getDaysBetweenDates(Date startdate, Date enddate)
{
    List<Date> dates = new ArrayList<Date>();
    Calendar calendar = new GregorianCalendar();
    calendar.setTime(startdate);

    while (calendar.getTime().before(enddate))
    {
        Date result = calendar.getTime();
        dates.add(result);
        calendar.add(Calendar.DATE, 1);
    }
    return dates;
}
18 голосов
/ 09 марта 2016

Streams

Редактировать: Joda-Time теперь устарела, изменил ответ, чтобы использовать вместо него Java 8.

Вот способ Java 8 с использованием потоков.

List<LocalDate> daysRange = Stream.iterate(startDate, date -> date.plusDays(1)).limit(numOfDays).collect(Collectors.toList());
12 голосов
/ 26 августа 2010

пожалуйста, найдите следующий код.

List<Date> dates = new ArrayList<Date>();

String str_date ="27/08/2010";
String end_date ="02/09/2010";

DateFormat formatter ; 

formatter = new SimpleDateFormat("dd/MM/yyyy");
Date  startDate = (Date)formatter.parse(str_date); 
Date  endDate = (Date)formatter.parse(end_date);
long interval = 24*1000 * 60 * 60; // 1 hour in millis
long endTime =endDate.getTime() ; // create your endtime here, possibly using Calendar or Date
long curTime = startDate.getTime();
while (curTime <= endTime) {
    dates.add(new Date(curTime));
    curTime += interval;
}
for(int i=0;i<dates.size();i++){
    Date lDate =(Date)dates.get(i);
    String ds = formatter.format(lDate);    
    System.out.println(" Date is ..." + ds);
}

вывод:

Дата ... 27.08.2010
Дата ... 28.08.2010
Дата ... 29.08.2010
Дата ... 30.08.2010
Дата ... 31.08.2010
Дата ... 01.09.2010
Дата ... 09.02.2010

3 голосов
/ 20 февраля 2017

Рекомендованные потоки данных

В Java 9 вы можете использовать следующий новый метод, LocalDate::datesUntil:

LocalDate start = LocalDate.of(2017, 2, 1);
LocalDate end = LocalDate.of(2017, 2, 28);

Stream<LocalDate> dates = start.datesUntil(end.plusDays(1));
List<LocalDate> list = dates.collect(Collectors.toList());

Новый метод datesUntil(...) работает с эксклюзивной датой окончания, отсюда и показано, как добавить день.

После получения потока вы можете использовать все функции, предоставляемые java.util.stream - или java.util.function -пакетами. Работа с потоками стала настолько простой по сравнению с более ранними подходами, основанными на пользовательских циклах for или while.


Или, если вы ищете потоковое решение, которое работает по умолчанию с включенными датами, но также может быть настроено иначе, тогда вы можете найти класс DateInterval в моей библиотеке Time4J интересным потому что он предлагает множество специальных функций для потоков данных, включая эффективный сплитератор, который работает быстрее, чем в Java-9:

PlainDate start = PlainDate.of(2017,  2, 1);
PlainDate end = start.with(PlainDate.DAY_OF_MONTH.maximized());
Stream<PlainDate> stream = DateInterval.streamDaily(start, end);

Или еще проще в случае полных месяцев:

Stream<PlainDate> februaryDates = CalendarMonth.of(2017, 2).streamDaily();
List<LocalDate> list = 
    februaryDates.map(PlainDate::toTemporalAccessor).collect(Collectors.toList());
3 голосов
/ 25 июля 2013

Что-то вроде этого должно определенно работать:

private List<Date> getListOfDaysBetweenTwoDates(Date startDate, Date endDate) {
    List<Date> result = new ArrayList<Date>();
    Calendar start = Calendar.getInstance();
    start.setTime(startDate);
    Calendar end = Calendar.getInstance();
    end.setTime(endDate);
    end.add(Calendar.DAY_OF_YEAR, 1); //Add 1 day to endDate to make sure endDate is included into the final list
    while (start.before(end)) {
        result.add(start.getTime());
        start.add(Calendar.DAY_OF_YEAR, 1);
    }
    return result;
}
3 голосов
/ 11 июня 2014

С Ламмой это выглядит в Java следующим образом:

    for (Date d: Dates.from(2014, 6, 29).to(2014, 7, 1).build()) {
        System.out.println(d);
    }

и выводом:

    Date(2014,6,29)
    Date(2014,6,30)
    Date(2014,7,1)
2 голосов
/ 22 апреля 2010

Одним из решений будет создание экземпляра Calendar и запуск цикла, увеличивая его поле Calendar.DATE, пока оно не достигнет желаемой даты. Кроме того, на каждом шаге вы должны создать экземпляр Date (с соответствующими параметрами) и поместить его в свой список.

Какой-то грязный код:

    public List<Date> getDatesBetween(final Date date1, final Date date2) {
    List<Date> dates = new ArrayList<Date>();

    Calendar calendar = new GregorianCalendar() {{
        set(Calendar.YEAR, date1.getYear());
        set(Calendar.MONTH, date1.getMonth());
        set(Calendar.DATE, date1.getDate());
    }};

    while (calendar.get(Calendar.YEAR) != date2.getYear() && calendar.get(Calendar.MONTH) != date2.getMonth() && calendar.get(Calendar.DATE) != date2.getDate()) {
        calendar.add(Calendar.DATE, 1);
        dates.add(new Date(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE)));
    }

    return dates;
}
2 голосов
/ 06 декабря 2016

С Java 8

public Stream<LocalDate> getDaysBetween(LocalDate startDate, LocalDate endDate) {
    return IntStream.range(0, (int) DAYS.between(startDate, endDate)).mapToObj(startDate::plusDays);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...