2010-12-26 179 views
93

En mi secuencia de comandos necesito realizar un conjunto de acciones a través del rango de fechas, dadas las fechas de inicio y finalización.
Proporcióneme una guía para lograr esto usando Java.¿Cómo iterar por el rango de Fechas en Java?

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

} 

sé que el código anterior es simplemente imposible, pero lo hago con el fin de mostrar que lo que me gustaría lograr.

Respuesta

132

Bueno, usted podría hacer algo como esto (usando Joda Time)

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

Me fondo recomiendo usar Joda Time sobre la incorporada en Date/Calendar clases.

+3

Gracias hombre, Te debo una –

+1

Para ampliar el punto sobre Joda Time: tratar de implementar correctamente este sí mismo es más difícil de lo que parece, debido a la esquina casos alrededor de cambios hacia y desde el horario de verano. – Raedwald

+0

+1 para Joda Time! – PaulP1975

114

JodaTime es agradable, sin embargo, para completar y/o si prefiere instalaciones provistas por API, estos son los enfoques API estándar.

Cuando comenzando con java.util.Date casos como a continuación:

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

Aquí está el legado java.util.Calendar enfoque en caso de que no se encuentra en Java8 aún:

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

Y aquí está el enfoque de Java8 java.time.LocalDate, básicamente exactamente el enfoque 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 desea iterar inclusive la fecha de finalización, luego use !start.after(end) y !date.isAfter(end) respectivamente.

22

Esta es esencialmente la misma respuesta BalusC dio, pero un poco más legible con un bucle while en lugar de un bucle 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); 
} 
+3

Esto no funcionará si la lógica implica declaraciones "continuar", mientras que la versión for loop de BalusC funciona con declaraciones continuas. –

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 estilo, usando las clases 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); 

Salida:

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

Alternativa:

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

¿puedes poner valores múltiplos? por ejemplo: solo lunes, jueves o ambos – delive

-1

Aquí es Java 8 código. Creo que este código resolverá tu problema. feliz Codificación

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

Este es el mejor y más fácil enfoque que puede seguir. –

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

Esto le ayudará a empezar a los 30 días atrás y recorrer hasta la fecha de hoy. puede cambiar fácilmente el rango de fechas y dirección.

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

¿Por qué no usar epoch y loop through fácilmente?

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

Puede escribir una clase como esta (implementando la interfaz del iterador) e iterar sobre ella.

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

y usarlo como:

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

} 
Cuestiones relacionadas