182 votes

Comment itérer dans une plage de dates en Java ?

Dans mon script, j'ai besoin d'effectuer un ensemble d'actions sur une plage de dates, étant donné une date de début et de fin.
Veuillez me donner des conseils pour réaliser ceci en utilisant Java.

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

}

Je sais que le code ci-dessus est tout simplement impossible, mais je le fais pour vous montrer ce que j'aimerais réaliser.

244voto

Jon Skeet Points 692016

Eh bien, vous pourriez faire quelque chose comme ça en utilisant L'API de temps de Java 8 pour ce problème spécifique java.time.LocalDate (ou l'équivalent Joda Time classes pour Java 7 et plus)

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

Je voudrais complètement recommande d'utiliser java.time (ou Joda Time) par rapport au système intégré Date / Calendar classes.

162voto

BalusC Points 498232

JodaTime est très bien, cependant, par souci d'exhaustivité et/ou si vous préférez les facilités fournies par l'API, voici les approches standard de l'API.

En commençant par java.util.Date comme ci-dessous :

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

Voici l'héritage java.util.Calendar au cas où vous ne seriez pas encore sous 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);
}

Et voici celui de Java8 java.time.LocalDate qui est en fait exactement la même que celle de 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);
}

Si vous voulez itérer inclusivement la date de fin, puis utilisez !start.after(end) y !date.isAfter(end) respectivement.

94voto

Martin Andersson Points 1869

Java 8 en utilisant le style java.time classes :

// 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);

Sortie :

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

Alternatif :

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

Java 9 a ajouté le datesUntil() méthode :

start.datesUntil(end.plusDays(1)).forEach(System.out::println);

30voto

Chris M. Points 552

C'est essentiellement la même réponse que BalusC a donnée, mais un peu plus lisible avec une boucle while à la place d'une boucle 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);
}

8voto

Mykhaylo Adamovych Points 1907

Apache Commons

    for (Date dateIter = fromDate; !dateIter.after(toDate); dateIter = DateUtils.addDays(dateIter, 1)) {
        // ...
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X