2010-12-26 10 views
93

In meinem Skript muss ich eine Reihe von Aktionen über einen Bereich von Daten durchführen, mit einem Start-und Enddatum.
Bitte geben Sie mir Anleitung, um dies mit Java zu erreichen.Wie durchlaufen Sie Datumsbereiche in Java?

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

} 

Ich weiß, der obige Code einfach unmöglich ist, aber ich tue es, um Ihnen zu zeigen, was ich erreichen möchte.

Antwort

132

Nun, könnte man so etwas tun (mit Joda Time)

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

Ich würde gründlich empfehlen Joda Zeit über die eingebaute in Date/Calendar Klassen.

+3

Dank Mann, ich schulde Ihnen ein –

+1

Um auf den Punkt zu Joda Zeit zu erweitern: Der Versuch, dies richtig zu implementieren selbst ist härter als man wegen der Ecke denken könnte Fälle um Änderungen in und von Sommerzeit. – Raedwald

+0

+1 für Joda Zeit! – PaulP1975

114

JodaTime ist nett, aber der Vollständigkeit halber und/oder wenn Sie API-Einrichtungen bevorzugen, hier sind die Standard-API-Ansätze.

Wenn mit java.util.Date Instanzen Anfahren wie unten:

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

Hier ist das Vermächtnis java.util.Calendar Ansatz, falls Sie nicht auf Java8 noch:

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

Und hier ist java.time.LocalDate Ansatz der Java8, im Grunde genau der JodaTime-Ansatz:

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

Wenn Sie das Enddatum einschließlich iterieren möchten, verwenden Sie !start.after(end) bzw. !date.isAfter(end). anstelle eines

22

Dies ist im Wesentlichen die gleiche Antwort BalusC gab, aber ein bisschen besser lesbar mit einer while-Schleife für Schleife:

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); 
} 
+3

Dies funktioniert nicht, wenn die Logik "continue" -Anweisungen enthält, während die for-Schleife-Version von BalusC mit Continue-Anweisungen arbeitet. –

2
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 
    } 

} 
0

Apache Commons

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

Java 8 Stil, unter Verwendung der java.time Klassen:

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

Ausgang:

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); 
} 
+0

können Sie mehrere Werte setzen? Zum Beispiel: nur Montag oder Donnerstag oder beide – delive

-1

Hier ist Java 8 Code. Ich denke, dass dieser Code dein Problem lösen wird. Glücklich 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 
+0

Dies ist die beste und einfachste Methode, die Sie verfolgen können. –

2
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); 
    } 
} 
0

Dies hilft Ihnen 30 Tage zurück und Schleife starten durch, bis das heutige Datum. Sie können den Bereich von Daten und Richtung leicht ändern.

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()); 
     } 
} 
1

Warum Epoch nicht einfach durchschleifen.

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

    } 
0

Sie können eine Klasse wie diese schreiben (Iterator-Schnittstelle implementieren) und darüber iterieren.

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

und verwenden Sie es mögen:

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

} 
Verwandte Themen