Как перебирать диапазон дат в Java?
в моем скрипте мне нужно выполнить набор действий через диапазон дат, учитывая дату начала и окончания.
Пожалуйста, предоставьте мне руководство для достижения этой цели с помощью Java.
for ( currentDate = starDate; currentDate < endDate; currentDate++) {
}
Я знаю, что приведенный выше код просто невозможен, но я делаю это для того, чтобы показать вам, чего я хотел бы достичь.
12 ответов:
Ну, вы могли бы сделать что-то подобное с помощью Java 8's time-API, для этой проблемы специально
java.time.LocalDate(эквивалент Джода Времени классы для Java 7 и старше)for (LocalDate date = startDate; date.isBefore(endDate); date = date.plusDays(1)) { ... }Я бы тщательно рекомендую использовать
java.time(или время Джоды) над встроеннымDate/Calendarклассы.
JodaTime хорош, однако, для полноты и / или если вы предпочитаете API-предоставляемые средства, вот стандартные подходы API.
при запуске с
java.util.Dateслучаях, как показано ниже:SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); Date startDate = formatter.parse("2010-12-20"); Date endDate = formatter.parse("2010-12-26");вот наследие
java.util.Calendarподход в случае, если вы еще не на 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); }и вот Java8 в
java.time.LocalDateподход, в основном именно подход 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); }если бы ты нравится повторять включительно конечная дата, затем используйте
!start.after(end)и!date.isAfter(end)соответственно.
Java 8 стиль, используя java.время классы:
// 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);выход:
2016-02-28 2016-02-29 2016-03-01 2016-03-02альтернатива:
LocalDate next = start.minusDays(1); while ((next = next.plusDays(1)).isBefore(end.plusDays(1))) { System.out.println(next); }Java 9 добавил datesUntil() способ:
start.datesUntil(end.plusDays(1)).forEach(System.out::println);
Это по сути один и тот же ответ BalusC дал, но немного более читаемым с помощью цикла while вместо цикла 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)) { // ... }
вот код Java 8. Я думаю, что этот код решит вашу проблему.Удачи В Кодировании
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
почему бы не использовать epoch и цикл через легко.
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); }
Это поможет вам начать 30 дней назад и цикл до сегодняшней даты. вы можете легко изменить диапазон дат и направления.
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()); } }
вы можете написать такой класс(реализующий интерфейс итератора) и перебирать его .
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; } }и использовать его как :
Iterator<Date> dateIterator = new DateIterator(startDate, endDate); while(dateIterator.hasNext()){ Date selectedDate = dateIterator .next(); }
мы можем перенести логику на различные методы:
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()); }тогда мы можем вызвать эти методы как:
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);выход будет:
[Пн дек 20 00: 00: 00 IST 2010, Вт дек 21 00:00: 00 IST 2010, Ср дек 22 00: 00: 00 IST 2010, Чт дек 23 00: 00: 00 IST 2010, Пт Дек 24 00: 00: 00 IST 2010, СБ 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]
Comments