In my script I need to perform a set of actions through range of dates, given a start and end date.
Please provide me guidance to achieve this using Java.
for ( currentDate = starDate; currentDate < endDate; currentDate++) {
}
I know the above code is simply impossible, but I do it in order to show you what I'd like to achieve.
Java 8 style, using the java.time 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);
Output:
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 added the datesUntil() method:
start.datesUntil(end.plusDays(1)).forEach(System.out::println);
This is essentially the same answer BalusC gave, but a bit more readable with a while loop in place of a for loop:
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);
}
Why not use epoch and loop through easily.
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);
}
JodaTime is nice, however, for the sake of completeness and/or if you prefer API-provided facilities, here are the standard API approaches.
When starting off with java.util.Date
instances like below:
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date startDate = formatter.parse("2010-12-20");
Date endDate = formatter.parse("2010-12-26");
Here's the legacy java.util.Calendar
approach in case you aren't on Java8 yet:
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);
}
And here's Java8's java.time.LocalDate
approach, basically exactly the JodaTime approach:
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);
}
If you'd like to iterate inclusive the end date, then use !start.after(end)
and !date.isAfter(end)
respectively.
The following snippet (uses java.time.format of Java 8) maybe used to iterate over a date range :
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
// Any chosen date format maybe taken
LocalDate startDate = LocalDate.parse(startDateString,formatter);
LocalDate endDate = LocalDate.parse(endDateString,formatter);
if(endDate.isBefore(startDate))
{
//error
}
LocalDate itr = null;
for (itr = startDate; itr.isBefore(endDate)||itr.isEqual(itr); itr = itr.plusDays(1))
{
//Processing goes here
}
The plusMonths()/plusYears() maybe chosen for time unit increment. Increment by a single day is being done in above illustration.
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);
}
}
You can try this:
OffsetDateTime currentDateTime = OffsetDateTime.now();
for (OffsetDateTime date = currentDateTime; date.isAfter(currentDateTime.minusYears(YEARS)); date = date.minusWeeks(1))
{
...
}
Here is Java 8 code. I think this code will solve your problem.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
This will help you start 30 days back and loop through until today's date. you can easily change range of dates and 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());
}
}
We can migrate the logic to various methods foe Java 7, Java 8 and 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());
}
Then we can invoke these methods as:
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);
The output would be:
[Mon Dec 20 00:00:00 IST 2010, Tue Dec 21 00:00:00 IST 2010, Wed Dec 22 00:00:00 IST 2010, Thu Dec 23 00:00:00 IST 2010, Fri Dec 24 00:00:00 IST 2010, Sat Dec 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]
You can write a class like it(implementing iterator interface) and iterate over it .
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;
}
}
and use it like :
Iterator<Date> dateIterator = new DateIterator(startDate, endDate);
while(dateIterator.hasNext()){
Date selectedDate = dateIterator .next();
}
Apache Commons
for (Date dateIter = fromDate; !dateIter.after(toDate); dateIter = DateUtils.addDays(dateIter, 1)) {
// ...
}
Source: Stackoverflow.com