fix next bug

This commit is contained in:
Looly 2022-04-14 01:16:59 +08:00
parent 46594efbcc
commit 2c399fd72a
3 changed files with 28 additions and 10 deletions

View File

@ -1,6 +1,7 @@
package cn.hutool.cron.pattern;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.CalendarUtil;
import cn.hutool.cron.pattern.matcher.PatternMatcher;
import cn.hutool.cron.pattern.parser.PatternParser;
@ -129,14 +130,19 @@ public class CronPattern {
}
/**
* 返回匹配到的下一个时间<br>
* TODO 周定义后结果错误需改进
* 返回匹配到的下一个时间
*
* @param calendar 时间
* @return 匹配到的下一个时间
*/
public Calendar nextMatchAfter(Calendar calendar) {
return nextMatchAfter(PatternUtil.getFields(calendar, true), calendar.getTimeZone());
Calendar next = nextMatchAfter(PatternUtil.getFields(calendar, true), calendar.getTimeZone());
if(false == match(next, true)){
next.set(Calendar.DAY_OF_MONTH, next.get(Calendar.DAY_OF_MONTH) + 1);
next = CalendarUtil.beginOfDay(next);
return nextMatchAfter(next);
}
return next;
}
@Override
@ -152,7 +158,7 @@ public class CronPattern {
*/
private boolean match(int[] fields) {
for (PatternMatcher matcher : matchers) {
if (matcher.match(fields[0], fields[1], fields[2], fields[3], fields[4], fields[5], fields[6])) {
if (matcher.match(fields)) {
return true;
}
}

View File

@ -62,6 +62,16 @@ public class PatternMatcher {
//region match
/**
* 给定时间是否匹配定时任务表达式
*
* @param fields 时间字段值{second, minute, hour, dayOfMonth, month, dayOfWeek, year}
* @return 如果匹配返回 {@code true}, 否则返回 {@code false}
*/
public boolean match(int[] fields) {
return match(fields[0], fields[1], fields[2], fields[3], fields[4], fields[5], fields[6]);
}
/**
* 给定时间是否匹配定时任务表达式
*
@ -74,7 +84,7 @@ public class PatternMatcher {
* @param year
* @return 如果匹配返回 {@code true}, 否则返回 {@code false}
*/
public boolean match(int second, int minute, int hour, int dayOfMonth, int month, int dayOfWeek, int year) {
private boolean match(int second, int minute, int hour, int dayOfMonth, int month, int dayOfWeek, int year) {
return ((second < 0) || matchers[0].match(second)) // 匹配秒非秒匹配模式下始终返回true
&& matchers[1].match(minute)// 匹配分
&& matchers[2].match(hour)// 匹配时
@ -127,10 +137,11 @@ public class PatternMatcher {
final int[] newValues = nextMatchValuesAfter(values);
for (int i = 0; i < newValues.length; i++) {
// 周无需设置
if(i != Part.DAY_OF_WEEK.ordinal()){
if (i != Part.DAY_OF_WEEK.ordinal()) {
setValue(calendar, Part.of(i), newValues[i]);
}
}
return calendar;
}
@ -158,7 +169,7 @@ public class PatternMatcher {
// 新值-1表示标识为回退
int nextValue = 0;
while (i >= 0) {
if(i == Part.DAY_OF_WEEK.ordinal()){
if (i == Part.DAY_OF_WEEK.ordinal()) {
// 周不参与计算
i--;
continue;
@ -182,7 +193,7 @@ public class PatternMatcher {
// 值产生回退向上查找变更值
if (-1 == nextValue) {
while (i <= Part.YEAR.ordinal()) {
if(i == Part.DAY_OF_WEEK.ordinal()){
if (i == Part.DAY_OF_WEEK.ordinal()) {
// 周不参与计算
i++;
continue;

View File

@ -91,9 +91,10 @@ public class CronPatternNextMatchTest {
@Test
public void nextMatchAfterByWeekTest(){
CronPattern pattern = new CronPattern("1 1 1 * * Sat *");
//
final DateTime time = DateUtil.parse("2022-04-01");
// 下个周六在4月9日
final DateTime time = DateUtil.parse("2022-04-03");
assert time != null;
final Calendar calendar = pattern.nextMatchAfter(time.toCalendar());
Assert.assertEquals("2022-04-09 01:01:01", DateUtil.date(calendar).toString());
}
}