diff --git a/jollyday-core/src/main/java/de/focus_shift/jollyday/core/parser/functions/FindWeekDayBetween.java b/jollyday-core/src/main/java/de/focus_shift/jollyday/core/parser/functions/FindWeekDayBetween.java index f525dc921..224242c10 100644 --- a/jollyday-core/src/main/java/de/focus_shift/jollyday/core/parser/functions/FindWeekDayBetween.java +++ b/jollyday-core/src/main/java/de/focus_shift/jollyday/core/parser/functions/FindWeekDayBetween.java @@ -3,16 +3,12 @@ import de.focus_shift.jollyday.core.spi.FixedWeekdayBetweenFixed; import java.time.LocalDate; -import java.util.Iterator; -import java.util.NoSuchElementException; import java.util.function.Function; -import java.util.stream.StreamSupport; +import java.util.stream.Stream; -import static java.util.Spliterator.IMMUTABLE; -import static java.util.Spliterator.ORDERED; -import static java.util.Spliterators.spliteratorUnknownSize; +import static java.time.temporal.ChronoUnit.DAYS; -public class FindWeekDayBetween implements Function, Iterable { +public class FindWeekDayBetween implements Function { private final LocalDate from; private final LocalDate to; @@ -24,40 +20,9 @@ public FindWeekDayBetween(final LocalDate from, final LocalDate to) { @Override public LocalDate apply(final FixedWeekdayBetweenFixed fwm) { - return StreamSupport.stream(spliteratorUnknownSize(iterator(), ORDERED | IMMUTABLE), false) + return Stream.iterate(from, date -> date.plusDays(1)) + .limit(DAYS.between(from, to) + 1) .filter(date -> date.getDayOfWeek() == fwm.weekday()) .findFirst().orElse(null); } - - @Override - public Iterator iterator() { - return new FindWeekDayBetweenIterator(from, to); - } - - private static final class FindWeekDayBetweenIterator implements Iterator { - - private LocalDate cursor; - private final LocalDate endDate; - - FindWeekDayBetweenIterator(final LocalDate startDate, final LocalDate endDate) { - this.cursor = startDate; - this.endDate = endDate; - } - - @Override - public boolean hasNext() { - return cursor.isBefore(endDate) || cursor.isEqual(endDate); - } - - @Override - public LocalDate next() { - if (!hasNext()) { - throw new NoSuchElementException("next date is after endDate which is not in range anymore."); - } - - final LocalDate current = cursor; - cursor = cursor.plusDays(1); - return current; - } - } } diff --git a/jollyday-core/src/test/java/de/focus_shift/jollyday/core/parser/functions/FindWeekDayBetweenTest.java b/jollyday-core/src/test/java/de/focus_shift/jollyday/core/parser/functions/FindWeekDayBetweenTest.java new file mode 100644 index 000000000..748c8690b --- /dev/null +++ b/jollyday-core/src/test/java/de/focus_shift/jollyday/core/parser/functions/FindWeekDayBetweenTest.java @@ -0,0 +1,85 @@ +package de.focus_shift.jollyday.core.parser.functions; + + +import de.focus_shift.jollyday.core.HolidayType; +import de.focus_shift.jollyday.core.spi.Fixed; +import de.focus_shift.jollyday.core.spi.FixedWeekdayBetweenFixed; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import java.time.DayOfWeek; +import java.time.LocalDate; +import java.time.Year; + +import static org.assertj.core.api.Assertions.assertThat; + +class FindWeekDayBetweenTest { + + @ParameterizedTest + @CsvSource({ + "MONDAY,2025-01-06", + "WEDNESDAY,2025-01-08", + "FRIDAY,2025-01-10", + }) + void ensureToFindFirstWeekdayBetweenTwoFixedDates(final DayOfWeek dayOfWeek, final LocalDate expectedDate) { + final LocalDate firstMonday = LocalDate.of(2025, 1, 6); + final LocalDate secondFriday = LocalDate.of(2025, 1, 17); + final LocalDate actualDate = new FindWeekDayBetween(firstMonday, secondFriday).apply(getFixedWeekdayBetweenFixed(dayOfWeek)); + assertThat(actualDate).isEqualTo(expectedDate); + } + + @Test + void ensureToReturnNullIfNoWeekdayWasFound() { + final LocalDate monday = LocalDate.of(2025, 1, 6); + final LocalDate tuesday = LocalDate.of(2025, 1, 7); + final LocalDate actualDate = new FindWeekDayBetween(monday, tuesday).apply(getFixedWeekdayBetweenFixed(DayOfWeek.WEDNESDAY)); + assertThat(actualDate).isNull(); + } + + private static FixedWeekdayBetweenFixed getFixedWeekdayBetweenFixed(final DayOfWeek dayOfWeek) { + + return new FixedWeekdayBetweenFixed() { + + @Override + public Fixed from() { + return null; + } + + @Override + public Fixed to() { + return null; + } + + @Override + public DayOfWeek weekday() { + return dayOfWeek; + } + + @Override + public String descriptionPropertiesKey() { + return ""; + } + + @Override + public HolidayType holidayType() { + return null; + } + + @Override + public Year validFrom() { + return null; + } + + @Override + public Year validTo() { + return null; + } + + @Override + public YearCycle cycle() { + return null; + } + }; + } +}