diff --git a/src/main/java/com/cronutils/model/time/SingleExecutionTime.java b/src/main/java/com/cronutils/model/time/SingleExecutionTime.java index b9faa39e..3e124c27 100755 --- a/src/main/java/com/cronutils/model/time/SingleExecutionTime.java +++ b/src/main/java/com/cronutils/model/time/SingleExecutionTime.java @@ -308,7 +308,7 @@ private ExecutionTimeResult potentialPreviousClosestMatch(final ZonedDateTime da final List year = yearsValueGenerator.generateCandidates(date.getYear(), date.getYear()); final Optional optionalDays = generateDays(cronDefinition, date); TimeNode days; - if (optionalDays.isPresent()) { + if (optionalDays.isPresent() && optionalDays.get().getValues().stream().anyMatch(i -> i <= date.getDayOfMonth())) { days = optionalDays.get(); } else { return new ExecutionTimeResult(toEndOfPreviousMonth(date), false); diff --git a/src/test/java/com/cronutils/Issue424Test.java b/src/test/java/com/cronutils/Issue424Test.java deleted file mode 100644 index c775c60d..00000000 --- a/src/test/java/com/cronutils/Issue424Test.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.cronutils; - -import com.cronutils.model.CronType; -import com.cronutils.model.definition.CronDefinition; -import com.cronutils.model.definition.CronDefinitionBuilder; -import com.cronutils.model.time.ExecutionTime; -import com.cronutils.parser.CronParser; -import org.junit.Ignore; -import org.junit.Test; - -import java.time.*; -import java.time.temporal.TemporalAdjusters; - -import static org.junit.Assert.assertEquals; - -@Ignore -public class Issue424Test { - @Test - public void test() { - CronDefinition cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ); - CronParser parser = new CronParser(cronDefinition); - ExecutionTime execution = ExecutionTime.forCron(parser.parse("0 0 12 ? * SUN#4 2020")); - LocalDate date = LocalDate.of(2021, 1, 1); - LocalTime time = LocalTime.of(0, 0, 0); - ZonedDateTime dateTime = ZonedDateTime.of(date, time, ZoneOffset.UTC); - for (int index = 0, size = 12; index < size; index++) { - dateTime = execution.lastExecution(dateTime).orElse(null); - assertEquals(LocalDateTime.of(2020, 12 - index, 1, 12, 0, 0).with(TemporalAdjusters.dayOfWeekInMonth(4, DayOfWeek.SUNDAY)), dateTime.toLocalDateTime()); - } - } -} diff --git a/src/test/java/com/cronutils/model/time/ExecutionTimeQuartzIntegrationTest.java b/src/test/java/com/cronutils/model/time/ExecutionTimeQuartzIntegrationTest.java index a570f148..bb423956 100755 --- a/src/test/java/com/cronutils/model/time/ExecutionTimeQuartzIntegrationTest.java +++ b/src/test/java/com/cronutils/model/time/ExecutionTimeQuartzIntegrationTest.java @@ -25,6 +25,7 @@ import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; +import java.time.temporal.TemporalAdjusters; import java.util.Date; import java.util.Optional; import java.util.TimeZone; @@ -841,6 +842,24 @@ public void testLastExecutionIssue312() { } } + /** + * Issue #424 + * https://github.com/jmrozanec/cron-utils/issues/424 + * Last execution time incorrectly calculated when using day of week expression + */ + @Test + public void testLastExecutionIssue424() { + // Every day at 20:00 + ExecutionTime executionTime = ExecutionTime.forCron(parser.parse("0 0 12 ? * SUN#4 2020")); + LocalDate date = LocalDate.of(2021, 1, 1); + LocalTime time = LocalTime.of(0, 0, 0); + ZonedDateTime dateTime = ZonedDateTime.of(date, time, ZoneOffset.UTC); + for (int index = 0, size = 12; index < size; index++) { + dateTime = executionTime.lastExecution(dateTime).orElse(null); + assertEquals(LocalDateTime.of(2020, 12 - index, 1, 12, 0, 0).with(TemporalAdjusters.dayOfWeekInMonth(4, DayOfWeek.SUNDAY)), dateTime.toLocalDateTime()); + } + } + private Duration getMinimumInterval(final String quartzPattern) { final ExecutionTime executionTime = ExecutionTime.forCron(parser.parse(quartzPattern)); final ZonedDateTime coolDay = ZonedDateTime.of(2016, 1, 1, 0, 0, 0, 0, UTC);