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; package cn.hutool.cron.pattern;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.CalendarUtil;
import cn.hutool.cron.pattern.matcher.PatternMatcher; import cn.hutool.cron.pattern.matcher.PatternMatcher;
import cn.hutool.cron.pattern.parser.PatternParser; import cn.hutool.cron.pattern.parser.PatternParser;
@ -129,14 +130,19 @@ public class CronPattern {
} }
/** /**
* 返回匹配到的下一个时间<br> * 返回匹配到的下一个时间
* TODO 周定义后结果错误需改进
* *
* @param calendar 时间 * @param calendar 时间
* @return 匹配到的下一个时间 * @return 匹配到的下一个时间
*/ */
public Calendar nextMatchAfter(Calendar calendar) { 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 @Override
@ -152,7 +158,7 @@ public class CronPattern {
*/ */
private boolean match(int[] fields) { private boolean match(int[] fields) {
for (PatternMatcher matcher : matchers) { 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; return true;
} }
} }

View File

@ -62,6 +62,16 @@ public class PatternMatcher {
//region match //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 * @param year
* @return 如果匹配返回 {@code true}, 否则返回 {@code false} * @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 return ((second < 0) || matchers[0].match(second)) // 匹配秒非秒匹配模式下始终返回true
&& matchers[1].match(minute)// 匹配分 && matchers[1].match(minute)// 匹配分
&& matchers[2].match(hour)// 匹配时 && matchers[2].match(hour)// 匹配时
@ -127,10 +137,11 @@ public class PatternMatcher {
final int[] newValues = nextMatchValuesAfter(values); final int[] newValues = nextMatchValuesAfter(values);
for (int i = 0; i < newValues.length; i++) { 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]); setValue(calendar, Part.of(i), newValues[i]);
} }
} }
return calendar; return calendar;
} }
@ -158,7 +169,7 @@ public class PatternMatcher {
// 新值-1表示标识为回退 // 新值-1表示标识为回退
int nextValue = 0; int nextValue = 0;
while (i >= 0) { while (i >= 0) {
if(i == Part.DAY_OF_WEEK.ordinal()){ if (i == Part.DAY_OF_WEEK.ordinal()) {
// 周不参与计算 // 周不参与计算
i--; i--;
continue; continue;
@ -182,7 +193,7 @@ public class PatternMatcher {
// 值产生回退向上查找变更值 // 值产生回退向上查找变更值
if (-1 == nextValue) { if (-1 == nextValue) {
while (i <= Part.YEAR.ordinal()) { while (i <= Part.YEAR.ordinal()) {
if(i == Part.DAY_OF_WEEK.ordinal()){ if (i == Part.DAY_OF_WEEK.ordinal()) {
// 周不参与计算 // 周不参与计算
i++; i++;
continue; continue;

View File

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