This commit is contained in:
Looly 2022-04-11 17:12:25 +08:00
parent ec1edde42c
commit 5b23619552
2 changed files with 50 additions and 13 deletions

View File

@ -124,6 +124,36 @@ public class PatternMatcher {
final Calendar calendar = Calendar.getInstance(zone);
calendar.set(Calendar.MILLISECOND, 0);
final int[] newValues = nextMatchValuesAfter(values);
for (int i = 0; i < newValues.length; i++) {
// 周无需设置
if(i != Part.DAY_OF_WEEK.ordinal()){
setValue(calendar, Part.of(i), newValues[i]);
}
}
return calendar;
}
/**
* 获取下一个匹配日期时间<br>
* 获取方法是先从年开始查找对应部分的下一个值
* <ul>
* <li>如果此部分下个值不变获取下一个部分</li>
* <li>如果此部分下个值大于给定值以下所有值置为最小值</li>
* <li>如果此部分下个值小于给定值回退到上一个值获取下一个新值之后的值置为最小值</li>
* </ul>
*
* <pre>
*
* &lt;-----------------&gt;
* </pre>
*
* @param values 时间字段值{second, minute, hour, dayOfMonth, month, dayOfWeek, year}
* @return {@link Calendar}毫秒数为0
*/
private int[] nextMatchValuesAfter(int[] values) {
final int[] newValues = values.clone();
int i = Part.YEAR.ordinal();
// 新值-1表示标识为回退
int nextValue = 0;
@ -131,7 +161,7 @@ public class PatternMatcher {
nextValue = matchers[i].nextAfter(values[i]);
if (nextValue > values[i]) {
// 此部分正常获取新值结束循环后续的部分置最小值
setValue(calendar, Part.of(i), nextValue);
newValues[i] = nextValue;
i--;
break;
} else if (nextValue < values[i]) {
@ -140,8 +170,7 @@ public class PatternMatcher {
nextValue = -1;// 标记回退查找
break;
}
// 值不变设置后检查下一个部分
setValue(calendar, Part.of(i), nextValue);
// 值不变检查下一个部分
i--;
}
@ -150,7 +179,7 @@ public class PatternMatcher {
while (i <= Part.YEAR.ordinal()) {
nextValue = matchers[i].nextAfter(values[i] + 1);
if (nextValue > values[i]) {
setValue(calendar, Part.of(i), nextValue);
newValues[i] = nextValue;
i--;
break;
}
@ -159,25 +188,22 @@ public class PatternMatcher {
}
// 修改值以下的字段全部归最小值
setToMin(calendar, i);
return calendar;
setToMin(newValues, i);
return newValues;
}
/**
* 设置从{@link Part#SECOND}到指定部分全部设置为最小值
*
* @param calendar {@link Calendar}
* @param toPart 截止的部分
* @return {@link Calendar}
* @param values 值数组
* @param toPart 截止的部分
*/
private Calendar setToMin(Calendar calendar, int toPart) {
private void setToMin(int[] values, int toPart) {
Part part;
for (int i = 0; i <= toPart; i++) {
part = Part.of(i);
setValue(calendar, part, getMin(part));
values[i] = getMin(part);
}
return calendar;
}
/**

View File

@ -3,6 +3,7 @@ package cn.hutool.cron.pattern;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Console;
import org.junit.Assert;
import org.junit.Test;
@ -87,4 +88,14 @@ public class CronPatternNextMatchTest {
Assert.assertTrue(pattern.match(calendar, true));
Assert.assertEquals("2022-01-12 00:12:23", DateUtil.date(calendar).toString());
}
@Test
public void nextMatchAfterByWeekTest(){
CronPattern pattern = new CronPattern("1 1 1 * * Sat *");
// 周五
final DateTime time = DateUtil.parse("2022-04-01");
assert time != null;
final Calendar calendar = pattern.nextMatchAfter(time.toCalendar());
Console.log(DateUtil.date(calendar));
}
}