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.
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.
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)
.
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);
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);
}
Apache Commons
for (Date dateIter = fromDate; !dateIter.after(toDate); dateIter = DateUtils.addDays(dateIter, 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
}
}
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);
}
}
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
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);
}
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]
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();
}
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());
}
}