Как перебрать диапазон дат в Java? - PullRequest
121 голосов
/ 26 декабря 2010

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

for ( currentDate = starDate; currentDate < endDate; currentDate++) {

}

Я знаюприведенный выше код просто невозможен, но я делаю это для того, чтобы показать вам, чего я хотел бы достичь.

Ответы [ 12 ]

167 голосов
/ 26 декабря 2010

Ну, вы могли бы сделать что-то подобное, используя API времени Java 8 , для этой задачи, в частности java.time.LocalDate (или эквивалентные Joda Time классыдля Java 7 и старше)

for (LocalDate date = startDate; date.isBefore(endDate); date = date.plusDays(1))
{
    ...
}

Я бы полностью рекомендовал бы использовать java.time (или Joda Time) по сравнению со встроенными Date / Calendar классами.

139 голосов
/ 26 декабря 2010

JodaTime хорош, однако, для полноты и / или если вы предпочитаете средства, предоставляемые API, вот стандартные подходы API.

При запуске с java.util.Date экземплярами, как показано ниже:

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date startDate = formatter.parse("2010-12-20");
Date endDate = formatter.parse("2010-12-26");

Вот унаследованный java.util.Calendar подход, если вы еще не работали на Java8:

Calendar start = Calendar.getInstance();
start.setTime(startDate);
Calendar end = Calendar.getInstance();
end.setTime(endDate);

for (Date date = start.getTime(); start.before(end); start.add(Calendar.DATE, 1), date = start.getTime()) {
    // Do your job here with `date`.
    System.out.println(date);
}

А вот подход Java8 java.time.LocalDate, в основном именно подход JodaTime:

LocalDate start = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate end = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

for (LocalDate date = start; date.isBefore(end); date = date.plusDays(1)) {
    // Do your job here with `date`.
    System.out.println(date);
}

Если вы хотите повторить включительно дату окончания, используйте !start.after(end) и !date.isAfter(end) соответственно.

65 голосов
/ 11 октября 2015

стиль Java 8 с использованием классов java.time :

// Monday, February 29 is a leap day in 2016 (otherwise, February only has 28 days)
LocalDate start = LocalDate.parse("2016-02-28"),
          end   = LocalDate.parse("2016-03-02");

// 4 days between (end is inclusive in this example)
Stream.iterate(start, date -> date.plusDays(1))
        .limit(ChronoUnit.DAYS.between(start, end) + 1)
        .forEach(System.out::println);

Выход:

2016-02-28
2016-02-29
2016-03-01
2016-03-02

Альтернатива:

LocalDate next = start.minusDays(1);
while ((next = next.plusDays(1)).isBefore(end.plusDays(1))) {
    System.out.println(next);
}

Java 9 добавлен dateUntil () метод:

start.datesUntil(end.plusDays(1)).forEach(System.out::println);
25 голосов
/ 08 марта 2013

Это, по сути, тот же ответ, который дал BalusC, но немного более читаемый с циклом while вместо цикла for:

Calendar start = Calendar.getInstance();
start.setTime(startDate);

Calendar end = Calendar.getInstance();
end.setTime(endDate);

while( !start.after(end)){
    Date targetDay = start.getTime();
    // Do Work Here

    start.add(Calendar.DATE, 1);
}
4 голосов
/ 31 июля 2015

Apache Commons

    for (Date dateIter = fromDate; !dateIter.after(toDate); dateIter = DateUtils.addDays(dateIter, 1)) {
        // ...
    }
4 голосов
/ 31 октября 2014
private static void iterateBetweenDates(Date startDate, Date endDate) {
    Calendar startCalender = Calendar.getInstance();
    startCalender.setTime(startDate);
    Calendar endCalendar = Calendar.getInstance();
    endCalendar.setTime(endDate);

    for(; startCalender.compareTo(endCalendar)<=0;
          startCalender.add(Calendar.DATE, 1)) {
        // write your main logic here
    }

}
3 голосов
/ 25 марта 2016
public static final void generateRange(final Date dateFrom, final Date dateTo)
{
    final Calendar current = Calendar.getInstance();
    current.setTime(dateFrom);

    while (!current.getTime().after(dateTo))
    {
        // TODO

        current.add(Calendar.DATE, 1);
    }
}
2 голосов
/ 21 августа 2018

Мы можем перенести логику в различные методы для Java 7, Java 8 и Java 9 :

public static List<Date> getDatesRangeJava7(Date startDate, Date endDate) {
    List<Date> datesInRange = new ArrayList<>();
    Calendar startCalendar = new GregorianCalendar();
    startCalendar.setTime(startDate);
    Calendar endCalendar = new GregorianCalendar();
    endCalendar.setTime(endDate);
    while (startCalendar.before(endCalendar)) {
        Date result = startCalendar.getTime();
        datesInRange.add(result);
        startCalendar.add(Calendar.DATE, 1);
    }
    return datesInRange;
}

public static List<LocalDate> getDatesRangeJava8(LocalDate startDate, LocalDate endDate) {
    int numOfDays = (int) ChronoUnit.DAYS.between(startDate, endDate);
    return IntStream.range(0, numOfDays)
            .mapToObj(startDate::plusDays)
            .collect(Collectors.toList());
}

public static List<LocalDate> getDatesRangeJava9(LocalDate startDate, LocalDate endDate) {
    return startDate.datesUntil(endDate).collect(Collectors.toList());
}

Тогда мы можем вызвать эти методы как:

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date startDate = formatter.parse("2010-12-20");
Date endDate = formatter.parse("2010-12-26");
List<Date> dateRangeList = getDatesRangeJava7(startDate, endDate);
System.out.println(dateRangeList);

LocalDate startLocalDate = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate endLocalDate = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
List<LocalDate> dateRangeList8 = getDatesRangeJava8(startLocalDate, endLocalDate);
System.out.println(dateRangeList8);
List<LocalDate> dateRangeList9 = getDatesRangeJava8(startLocalDate, endLocalDate);
System.out.println(dateRangeList9);

Вывод будет:

[Пн 20 декабря 00:00:00 IST 2010, вторник 21 00:00:00 IST 2010, ср. Дек. 22 00:00:00 IST 2010, четверг, 23 00:00:00 IST 2010, пт, 24 декабря 00:00:00 IST 2010, суббота, 25 декабря 00:00:00 IST 2010]

[2010-12-20, 2010-12-21, 2010-12-22, 2010-12-23, 2010-12-24, 2010-12-25]

[2010-12-20, 2010-12-21, 2010-12-22, 2010-12-23, 2010-12-24, 2010-12-25]

2 голосов
/ 01 июня 2017

Почему бы не использовать эпоху и легко проходить.

long startDateEpoch = new java.text.SimpleDateFormat("dd/MM/yyyy").parse(startDate).getTime() / 1000;

    long endDateEpoch = new java.text.SimpleDateFormat("dd/MM/yyyy").parse(endDate).getTime() / 1000;


    long i;
    for(i=startDateEpoch ; i<=endDateEpoch; i+=86400){

        System.out.println(i);

    }
2 голосов
/ 28 декабря 2015

Вот код Java 8.Я думаю, что этот код решит вашу проблему. Happy Coding

    LocalDate start = LocalDate.now();
    LocalDate end = LocalDate.of(2016, 9, 1);//JAVA 9 release date
    Long duration = start.until(end, ChronoUnit.DAYS);
    System.out.println(duration);
     // Do Any stuff Here there after
    IntStream.iterate(0, i -> i + 1)
             .limit(duration)
             .forEach((i) -> {});
     //old way of iteration
    for (int i = 0; i < duration; i++)
     System.out.print("" + i);// Do Any stuff Here
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...