web-dev-qa-db-fra.com

Comment parcourir la plage de dates en Java?

Dans mon script, je dois effectuer un ensemble d’actions sur une plage de dates, en fonction des dates de début et de fin.
S'il vous plaît me donner des conseils pour y parvenir 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.

122
user531743

Eh bien, vous pourriez faire quelque chose comme ceci en utilisant API temporelle de Java 8 , pour ce problème en particulier Java.time.LocalDate (ou l’équivalent Joda Time classes pour Java 7 et plus ancien)

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

Je recommanderais complètement d'utiliser Java.time (ou Joda Time) sur les classes Date/Calendar intégrées.

170
Jon Skeet

JodaTime est Nice, cependant, par souci d'exhaustivité et/ou si vous préférez les installations fournies par l'API, voici les approches standard de l'API.

Lorsque vous démarrez avec _Java.util.Date_ instances 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'approche _Java.util.Calendar_ si vous n'êtes pas encore sur 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 l'approche _Java.time.LocalDate_ de Java8, essentiellement l'approche 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 souhaitez itérer y compris la date de fin, utilisez respectivement !start.after(end) et !date.isAfter(end).

140
BalusC

Java 8 en utilisant les classes 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);

Sortie:

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

Alternative:

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

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

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

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);
}
25
Chris M.

Apache Commons

    for (Date dateIter = fromDate; !dateIter.after(toDate); dateIter = DateUtils.addDays(dateIter, 1)) {
        // ...
    }
5
Mykhaylo Adamovych
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
    }

}
4
kushal agrawal
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);
    }
}
3
kayz1

Voici le code Java 8. Je pense que ce code résoudra votre problème .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
2
jatin Goyal

Pourquoi ne pas utiliser Epoch et faire une boucle facilement.

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
mridul4c

Nous pouvons migrer la logique vers différentes méthodes ennemies Java 7, Java 8 et 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());
}

Ensuite, nous pouvons invoquer ces méthodes en tant que:

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

La sortie serait:

[Lun 20 déc 00:00:00:00 IST 2010, mar 21 déc 00:00:00 IST 2010, mer 22 déc 00:00:00 IST 2010, jeu déc 23 min 00:00:00 IST 2010, vendredi 24 déc 00 00: 00:00 IST 2010, sam. Déc 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
i_am_zero

Vous pouvez écrire une classe comme celle-ci (implémenter l'interface d'itérateur) et effectuer une itération dessus.

public class DateIterator implements Iterator<Date>, Iterable<Date>
{

 private Calendar end = Calendar.getInstance();
 private Calendar current = Calendar.getInstance();

 public DateIterator(Date start, Date end)
 {
     this.end.setTime(end);
     this.end.add(Calendar.DATE, -1);
     this.current.setTime(start);
     this.current.add(Calendar.DATE, -1);
 }

 @Override
 public boolean hasNext()
 {
     return !current.after(end);
 }

 @Override
 public Date next()
 {
     current.add(Calendar.DATE, 1);
     return current.getTime();
 }

 @Override
 public void remove()
 {
     throw new UnsupportedOperationException(
        "Cannot remove");
 }

 @Override
 public Iterator<Date> iterator()
 {
     return this;
 }
}

et l'utiliser comme:

Iterator<Date> dateIterator = new DateIterator(startDate, endDate);
while(dateIterator.hasNext()){
      Date selectedDate = dateIterator .next();

}
1
jdev

Cela vous aidera à commencer 30 jours en arrière et à boucler jusqu'à la date d'aujourd'hui. vous pouvez facilement changer la plage de dates et la direction.

private void iterateThroughDates() throws Exception {
    Calendar start = Calendar.getInstance();
    start.add(Calendar.DATE, -30);
    Calendar end = Calendar.getInstance();
    for (Calendar date = start; date.before(end); date.add(Calendar.DATE, 1))
        {
        System.out.println(date.getTime());
        }
}
0
Januka samaranyake