cron-utils
cron-utils copied to clipboard
[potential bug] ExecutionTime.nextExecution returns Empty When time is beyond 2099 years
Hey guys, we find an issue in latest cron-utils release: ExecutionTime.nextExecution will return Empty when time is beyond 2099 years. The following is my test code
In the test class, I use 12/31/2099 as the current time and try to find next execution time after one month. The result I get is empty. Please check and let me know if I am doing a wrong way or its a bug of the library.
class app `
import static com.cronutils.model.CronType.QUARTZ; import static com.cronutils.model.definition.CronDefinitionBuilder.instanceDefinitionFor;
import java.time.ZonedDateTime; import java.util.Optional;
import com.cronutils.model.Cron; import com.cronutils.model.time.ExecutionTime; import com.cronutils.parser.CronParser;
public class app { private static final String CRON_START = "cron("; private static final int CRON_OFFSET = CRON_START.length(); private static final CronParser CRON_PARSER = new CronParser(instanceDefinitionFor(QUARTZ));
private static Cron getCronExpression(String scheduleExpression, String scheduleName) throws Exception {
// This method will parse cron("EXPRESSION") and return quartz cron.
StringBuilder cronExpression = new StringBuilder();
// Adding 0 because Quartz supports seconds fields.
cronExpression.append("0 ");
cronExpression.append(scheduleExpression.substring(CRON_OFFSET, scheduleExpression.length() - 1));
try {
Cron quartzExpression = CRON_PARSER.parse(cronExpression.toString());
quartzExpression.validate();
return quartzExpression;
}
catch (Exception e) {
throw e;
}
}
public static Optional<ZonedDateTime> getNextNthExecutionTime(int n, ZonedDateTime startTime,
String scheduleExpression, String scheduleName) throws Exception {
Cron cronExpression = getCronExpression(scheduleExpression, scheduleName);
ExecutionTime executionTime = ExecutionTime.forCron(cronExpression);
Optional<ZonedDateTime> nextRun = Optional.of(startTime);
for (int i=0; i<n; i++) {
nextRun = executionTime.nextExecution(nextRun.get());
if (!nextRun.isPresent()) {
throw new RuntimeException("failed");
}
}
return nextRun;
}
} `
test class `
import static org.junit.Assert.assertEquals;
import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.Optional;
import org.junit.Test;
public class test_app {
@Test
public void test() throws Exception {
ZonedDateTime currentRun = ZonedDateTime.of(2099,12,31,9,
0,0,0, ZoneId.of("America/Los_Angeles"));
Optional<ZonedDateTime> targetRun = app.getNextNthExecutionTime(1, currentRun,
"cron(0 9 L 1/2 ? *)", "Sched1");
ZonedDateTime expectedRun = ZonedDateTime.of(2100,2,29,9,
0,0,0, ZoneId.of("America/Los_Angeles"));
assertEquals("Next Nth execution date doesn't match", expectedRun, targetRun.get());
}
} `