61 votes

Java 8 LocalDate - Comment puis-je obtenir toutes les dates entre deux dates?

Est-il un usablility pour obtenir toutes les dates entre deux dates dans le nouveau java.time API?

Disons que j'ai cette partie de code:

@Test
public void testGenerateChartCalendarData() {
    LocalDate startDate = LocalDate.now();

    LocalDate endDate = startDate.plusMonths(1);
    endDate = endDate.withDayOfMonth(endDate.lengthOfMonth());
}

Maintenant j'ai besoin de toutes les dates entre startDate et endDate.

Je pensais à obtenir l' daysBetween de ces deux dates et itérer sur:

long daysBetween = ChronoUnit.DAYS.between(startDate, endDate);

for(int i = 0; i <= daysBetween; i++){
    startDate.plusDays(i); //...do the stuff with the new date...
}

Est-il une meilleure façon d'obtenir les dates?

89voto

assylias Points 102015

En supposant que vous principalement souhaitez effectuer une itération sur la plage de date, il serait judicieux de créer un DateRange classe qui est itératif. Qui vous permettent d'écrire:

for (LocalDate d : DateRange.between(startDate, endDate)) ...

Quelque chose comme:

public class DateRange implements Iterable<LocalDate> {

  private final LocalDate startDate;
  private final LocalDate endDate;

  public DateRange(LocalDate startDate, LocalDate endDate) {
    //check that range is valid (null, start < end)
    this.startDate = startDate;
    this.endDate = endDate;
  }

  @Override
  public Iterator<LocalDate> iterator() {
    return stream().iterator();
  }

  public Stream<LocalDate> stream() {
    return Stream.iterate(startDate, d -> d.plusDays(1))
                 .limit(ChronoUnit.DAYS.between(startDate, endDate) + 1);
  }

  public List<LocalDate> toList() { //could also be built from the stream() method
    List<LocalDate> dates = new ArrayList<> ();
    for (LocalDate d = startDate; !d.isAfter(endDate); d = d.plusDays(1)) {
      dates.add(d);
    }
    return dates;
  }
}

Il serait judicieux d'ajouter est égal à & hashcode méthodes, les méthodes de lecture, peut-être un statique usine + constructeur privé pour correspondre au style de codage de la version Java de l'API du temps etc.

79voto

Flown Points 2984

D'abord, vous pouvez utiliser un TemporalAdjuster pour obtenir le dernier jour du mois. Suivant l' Stream API offre Stream::iterate qui est le bon outil pour votre problème.

LocalDate start = LocalDate.now();
LocalDate end = LocalDate.now().plusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
List<LocalDate> dates = Stream.iterate(start, date -> date.plusDays(1))
    .limit(ChronoUnit.DAYS.between(start, end))
    .collect(Collectors.toList());
System.out.println(dates.size());
System.out.println(dates);

48voto

Durgpal Singh Points 81

Java 9

En Java 9, LocalDate classe a été renforcée avec la LocalDate.datesUntil(LocalDate endExclusive) méthode, qui renvoie toutes les dates à l'intérieur d'une fourchette de dates en tant que Stream<LocalDate>.

List<LocalDate> dates = startDate.datesUntil(endDate).collect(Collectors.toList());

9voto

N.J.Dawson Points 488

Vous pouvez utiliser le .isAfter et .plusDays pour ce faire sur une boucle. Je ne dirais pas mieux que je n'ai pas fait une énorme quantité de recherche sur le sujet, mais je peux dire avec confiance qu'il utilise le Java 8 API et est une légère variante.

LocalDate startDate = LocalDate.now();
LocalDate endDate = startDate.plusMonths(1);
while (!startDate.isAfter(endDate)) {
 System.out.println(startDate);
 startDate = startDate.plusDays(1);
}

Sortie

2016-07-05
2016-07-06
...
2016-08-04
2016-08-05

Exemple Ici

6voto

Todd Points 4949

Vous pouvez créer un stream de LocalDate objets. J'ai eu ce problème aussi, et j'ai publié ma solution en tant que java-flux temporel sur github.

À l'aide de votre exemple...

LocalDateStream
    .from(LocalDate.now())
    .to(1, ChronoUnit.MONTHS)
    .stream()
    .collect(Collectors.toList());

C'est plus ou moins équivalent à d'autres solutions proposées ici, mais il prend soin de tous de la date de mathématiques et de savoir quand s'arrêter. Vous pouvez fournir des ou d'un parent dates de fin, et lui dire comment beaucoup de temps pour sauter à chaque itération (la valeur par défaut ci-dessus est un jour).

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