Проход по диапазону дат в Java: правильный цикл итерации
Быстрый ответ
Для проведения итерации по диапазону дат в Java используйте класс LocalDate
и метод plusDays
:
LocalDate start = LocalDate.of(2023, 1, 1);
LocalDate end = LocalDate.of(2023, 1, 5);
for (; !start.isAfter(end); start = start.plusDays(1)) {
System.out.println(start);
}
Помните, что для процесса итерации необходимо перемещаться от начальной даты к конечной, при этом увеличивая значение даты на один день за цикл.
Альтернативные способы перемещения во времени
Потоки: изящный подход
Начиная с Java 9, была введена функция datesUntil()
, генерирующая поток Stream<LocalDate>
, который идеально подходит для итерации по датам:
LocalDate start = LocalDate.of(2023, 1, 1);
LocalDate end = LocalDate.of(2023, 1, 5);
start.datesUntil(end.plusDays(1)).forEach(System.out::println);
Данный метод обеспечивает функциональное прохождение дат без создания лишних вычислений и учета високосных лет.
Когда необходимо подсчитать «дни»
Если вам требуется узнать количество дней между двумя датами, воспользуйтесь ChronoUnit.DAYS.between
:
long daysBetween = ChronoUnit.DAYS.between(start, end);
Это позволит получить требуемое количество дней без лишнего программного кода.
Ода классической музыке: цикл while
Цикл while
зачастую оказывается удобен и прозрачен благодаря своей традиционности:
while (!start.isAfter(end)) {
System.out.println(start);
start = start.plusDays(1);
}
Он идеально подойдет тем, кто отдаёт предпочтение классическим методам.
Визуализация
Воспринимайте каждую дату как своего рода ступеньку. «Переход» с одной ступеньки на следующую осуществляется посредством выполнения plusDays(1)
:
🗓️1 = Начальная дата
🗓️2 = Каждая последующая дата
🏁 = Конечная дата
🗓️1--🗓️2--🗓️2--🗓️2--🏁
Представленная выше иллюстрация наглядно отображает процесс итерации по датам.
Продвинутый раздел: дополнительные сценарии и потенциальные риски
Обратитесь к ДеЛориану для версий Java, предшествующих 8-й версии
Для версий Java, предшествующих 8-й, существует библиотека Joda Time:
DateTime start = new DateTime(2023, 1, 1, 0, 0);
DateTime end = new DateTime(2023, 1, 5, 0, 0);
while (start.isBefore(end)) {
System.out.println(start);
start = start.plusDays(1);
}
Не забудьте добавить Joda Time в зависимости вашего проекта.
Иногда датами управляют при помощи строкового представления
В разработке иногда приходится работать с датами, представленными в строковом формате:
LocalDate start = LocalDate.parse("2023-01-01");
LocalDate end = LocalDate.parse("2023-01-05");
Ключевым является то, чтобы строка, содержащая дату, соответствовала стандарту ISO-8601. Это предотвратит возникновение DateTimeParseException
.
Погружение в прошлое с помощью Calendar
Classic Java использует класс Calendar
для работы с датами:
Calendar start = new GregorianCalendar(2023, Calendar.JANUARY, 1);
Calendar end = new GregorianCalendar(2023, Calendar.JANUARY, 5);
while (start.before(end)) {
System.out.println(start.getTime());
start.add(Calendar.DATE, 1);
}
Несмотря на то что это самый старомодный и неудобный подход, иногда он оказывается единственно доступным.
Когда вы работаете в окружении старых и новых форматов дат
При работе с java.util.Date
рекомендуется преобразовывать его в формат LocalDate
:
Date oldDate = new Date();
LocalDate newDate = oldDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
Это пригодится в случае работы с устаревшим программным кодом.
Полезные материалы
- java.time (Java Platform SE 8) — официальная документация по API Java 8 для работы со временем и датами.
- Руководство по работе с Date and Time в Java — все, что стоит знать о работе с временем и датами в Java.
- Stream (Java Platform SE 8) — глубокое погружение в потоки в контексте Java 8.