diff --git a/hutool-cron/src/main/java/cn/hutool/cron/pattern/matcher/PatternMatcher.java b/hutool-cron/src/main/java/cn/hutool/cron/pattern/matcher/PatternMatcher.java
index 554560fab..97861425b 100644
--- a/hutool-cron/src/main/java/cn/hutool/cron/pattern/matcher/PatternMatcher.java
+++ b/hutool-cron/src/main/java/cn/hutool/cron/pattern/matcher/PatternMatcher.java
@@ -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;
+ }
+
+ /**
+ * 获取下一个匹配日期时间
+ * 获取方法是,先从年开始查找对应部分的下一个值:
+ *
+ * 秒 分 时 日 月 周 年 + * 下 <-----------------> 上 + *+ * + * @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; } /** diff --git a/hutool-cron/src/test/java/cn/hutool/cron/pattern/CronPatternNextMatchTest.java b/hutool-cron/src/test/java/cn/hutool/cron/pattern/CronPatternNextMatchTest.java index 490760ffe..590397849 100644 --- a/hutool-cron/src/test/java/cn/hutool/cron/pattern/CronPatternNextMatchTest.java +++ b/hutool-cron/src/test/java/cn/hutool/cron/pattern/CronPatternNextMatchTest.java @@ -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)); + } }