Various bug fixes in CronExpression

This commit makes various bug fixes in CronExpression and related files.

Closes gh-27136
This commit is contained in:
Arjen Poutsma
2021-07-07 10:56:07 +02:00
parent 94f56a2684
commit 76b1c0f1fc
4 changed files with 24 additions and 6 deletions

View File

@@ -66,8 +66,9 @@ public final class CronExpression {
CronField daysOfWeek,
String expression) {
// reverse order, to make big changes first
// to make sure we end up at 0 nanos, we add an extra field
this.fields = new CronField[]{CronField.zeroNanos(), seconds, minutes, hours, daysOfMonth, months, daysOfWeek};
this.fields = new CronField[]{daysOfWeek, months, daysOfMonth, hours, minutes, seconds, CronField.zeroNanos()};
this.expression = expression;
}

View File

@@ -230,9 +230,7 @@ abstract class CronField {
* Elapse the given temporal for the difference between the current
* value of this field and the goal value. Typically, the returned
* temporal will have the given goal as the current value for this type,
* but this is not the case for {@link #DAY_OF_MONTH}. For instance,
* if {@code goal} is 31, and {@code temporal} is April 16th,
* this method returns May 1st, because April 31st does not exist.
* but this is not the case for {@link #DAY_OF_MONTH}.
* @param temporal the temporal to elapse
* @param goal the goal value
* @param <T> the type of temporal
@@ -247,8 +245,9 @@ abstract class CronField {
return cast(temporal.with(this.field, goal));
}
else {
// goal is invalid, eg. 29th Feb, lets try to get as close as possible
return this.field.getBaseUnit().addTo(temporal, goal - current);
// goal is invalid, eg. 29th Feb, so roll forward
long amount = range.getMaximum() - current + 1;
return this.field.getBaseUnit().addTo(temporal, amount);
}
}
else {

View File

@@ -334,6 +334,9 @@ final class QuartzCronField extends CronField {
// We ended up before the start, roll forward and try again
temporal = this.rollForwardType.rollForward(temporal);
result = adjust(temporal);
if (result != null) {
result = type().reset(result);
}
}
}
return result;