From 0198427bd33cfcd2c3b28b6f62520487ded90d50 Mon Sep 17 00:00:00 2001 From: wqh <1241409260@qq.com> Date: Wed, 20 Aug 2025 10:07:34 +0800 Subject: [PATCH] Fix 4006 --- .../pattern/matcher/BoolArrayMatcher.java | 16 ++++++++++++++- .../pattern/matcher/DayOfMonthMatcher.java | 11 ++++++++++ .../cron/pattern/matcher/PatternMatcher.java | 6 +++--- .../cn/hutool/cron/pattern/Issue4006Test.java | 20 +++++++++++++++++++ 4 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 hutool-cron/src/test/java/cn/hutool/cron/pattern/Issue4006Test.java diff --git a/hutool-cron/src/main/java/cn/hutool/cron/pattern/matcher/BoolArrayMatcher.java b/hutool-cron/src/main/java/cn/hutool/cron/pattern/matcher/BoolArrayMatcher.java index d60909ec5..ad0961951 100644 --- a/hutool-cron/src/main/java/cn/hutool/cron/pattern/matcher/BoolArrayMatcher.java +++ b/hutool-cron/src/main/java/cn/hutool/cron/pattern/matcher/BoolArrayMatcher.java @@ -18,6 +18,10 @@ public class BoolArrayMatcher implements PartMatcher { * 用户定义此字段的最小值 */ private final int minValue; + /** + * 用户定义此字段的最大值 + */ + private final int maxValue; private final boolean[] bValues; /** @@ -29,13 +33,15 @@ public class BoolArrayMatcher implements PartMatcher { Assert.isTrue(CollUtil.isNotEmpty(intValueList), "Values must be not empty!"); bValues = new boolean[Collections.max(intValueList) + 1]; int min = Integer.MAX_VALUE; + int max = Integer.MIN_VALUE; for (Integer value : intValueList) { min = Math.min(min, value); + max = Math.max(max, value); bValues[value] = true; } this.minValue = min; + this.maxValue = max; } - @Override public boolean match(Integer value) { if (null == value || value >= bValues.length) { @@ -69,6 +75,14 @@ public class BoolArrayMatcher implements PartMatcher { public int getMinValue() { return this.minValue; } + /** + * 获取表达式定义的最大值 + * + * @return 最大值 + */ + public int getMaxValue() { + return this.maxValue; + } @Override public String toString() { diff --git a/hutool-cron/src/main/java/cn/hutool/cron/pattern/matcher/DayOfMonthMatcher.java b/hutool-cron/src/main/java/cn/hutool/cron/pattern/matcher/DayOfMonthMatcher.java index 0ce10436c..634aa1db7 100644 --- a/hutool-cron/src/main/java/cn/hutool/cron/pattern/matcher/DayOfMonthMatcher.java +++ b/hutool-cron/src/main/java/cn/hutool/cron/pattern/matcher/DayOfMonthMatcher.java @@ -50,8 +50,19 @@ public class DayOfMonthMatcher extends BoolArrayMatcher { return value == Month.getLastDay(month - 1, isLeapYear); } + @Deprecated public boolean isLast() { return match(31); } + /** + * 检查value是否大于等于这个月的最大天 + * @param value 被检查的值 + * @return + */ + public boolean isLastDay(int value) { + if(value>=getMaxValue()) return true; + return false; + } + } 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 65dfe6bec..f91dae00b 100755 --- 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 @@ -192,7 +192,7 @@ public class PatternMatcher { // pr#1189 if (i == Part.DAY_OF_MONTH.ordinal() && matchers[i] instanceof DayOfMonthMatcher - && ((DayOfMonthMatcher) matchers[i]).isLast()) { + && ((DayOfMonthMatcher) matchers[i]).isLastDay(values[i])) { int newMonth = newValues[Part.MONTH.ordinal()]; int newYear = newValues[Part.YEAR.ordinal()]; nextValue = getLastDay(newMonth, newYear); @@ -226,7 +226,7 @@ public class PatternMatcher { continue; } else if (i == Part.DAY_OF_MONTH.ordinal() && matchers[i] instanceof DayOfMonthMatcher - && ((DayOfMonthMatcher) matchers[i]).isLast()) { + && ((DayOfMonthMatcher) matchers[i]).isLastDay(values[i])) { int newMonth = newValues[Part.MONTH.ordinal()]; int newYear = newValues[Part.YEAR.ordinal()]; nextValue = getLastDay(newMonth, newYear); @@ -259,7 +259,7 @@ public class PatternMatcher { part = Part.of(i); if (part == Part.DAY_OF_MONTH && get(part) instanceof DayOfMonthMatcher - && ((DayOfMonthMatcher) get(part)).isLast()) { + && ((DayOfMonthMatcher) get(part)).isLastDay(values[i])) { int newMonth = values[Part.MONTH.ordinal()]; int newYear = values[Part.YEAR.ordinal()]; values[i] = getLastDay(newMonth, newYear); diff --git a/hutool-cron/src/test/java/cn/hutool/cron/pattern/Issue4006Test.java b/hutool-cron/src/test/java/cn/hutool/cron/pattern/Issue4006Test.java new file mode 100644 index 000000000..cea735ebc --- /dev/null +++ b/hutool-cron/src/test/java/cn/hutool/cron/pattern/Issue4006Test.java @@ -0,0 +1,20 @@ +package cn.hutool.cron.pattern; + +import cn.hutool.core.date.DateTime; +import org.junit.jupiter.api.Test; + +import java.util.Date; + +public class Issue4006Test { + @Test + void testCron() { +// String cron = "0 0 0 */1 * ?"; + String cron = "0 0 0 */1 * ? *"; + DateTime judgeTime = DateTime.of(new Date()); + CronPattern cronPattern = new CronPattern(cron); + + System.out.println("cronPattern = " + cronPattern); + Date nextDate = CronPatternUtil.nextDateAfter(cronPattern, judgeTime, true); + System.out.println("nextDate = " + nextDate); + } +}