Comment parcourir la plage de Dates en Java?
Dans mon script, j'ai besoin d'effectuer un ensemble d'actions à travers la plage de dates, étant donné une date de début et de fin.
Veuillez me fournir 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 afin de vous montrer ce que je voudrais réaliser.
12 réponses
Eh bien, vous pouvez faire quelque chose comme ça en utilisant time-API de Java 8 , pour ce problème spécifiquement java.time.LocalDate
(ou l'équivalent Joda temps classes pour Java 7 et plus)
for (LocalDate date = startDate; date.isBefore(endDate); date = date.plusDays(1))
{
...
}
Je à fond recommande d'utiliser java.time
(ou Joda Time) sur le haut-parleur Date
/Calendar
cours.
JodaTime est agréable, cependant, par souci d'exhaustivité et/ou si vous préférez les installations fournies par L'API, voici les approches API standard.
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'héritage java.util.Calendar
approche au cas où 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 Java8 java.time.LocalDate
approche, fondamentalement exactement 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 inclusif la date de fin, utilisez !start.after(end)
et !date.isAfter(end)
respectivement.
Java 8 style, en utilisant le java.temps 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
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éthodedatesUntil () :
start.datesUntil(end.plusDays(1)).forEach(System.out::println);
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);
}
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);
}
}
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
}
}
Apache Commons
for (Date dateIter = fromDate; !dateIter.after(toDate); dateIter = DateUtils.addDays(dateIter, 1)) {
// ...
}
Voici le code Java 8. Je pense que ce code va résoudre votre problème.Codage Heureux
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
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);
}
Cela vous aidera à commencer 30 jours en arrière et boucle jusqu'à la date d'aujourd'hui. vous pouvez facilement changer la plage de dates et de 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());
}
}
Vous pouvez écrire une classe comme elle (implémentant l'interface iterator) et itérer 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();
}
Nous pouvons migrer la logique vers différentes méthodes:
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 comme:
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 Dec 20 00: 00: 00 IST 2010, Mar Dec 21 00: 00: 00 IST 2010, mer Dec 22 00:00:00 IST 2010, Thu Dec 23 00:00:00 IST 2010, Ven Déc 24 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]