From 29bcdc91cdcf840776ea617583a272204092d19e Mon Sep 17 00:00:00 2001 From: wqh <1241409260@qq.com> Date: Thu, 21 Aug 2025 00:22:34 +0800 Subject: [PATCH] fix:4006 --- .../pattern/matcher/BoolArrayMatcher.java | 1 - .../pattern/matcher/DayOfMonthMatcher.java | 13 ++++++++++++ .../cron/pattern/matcher/PatternMatcher.java | 20 +++++++++++++------ .../java/cn/hutool/cron/TaskTableTest.java | 0 .../pattern/CronPatternNextMatchTest.java | 10 +++++----- .../cn/hutool/cron/pattern/Issue4006Test.java | 20 +++++++++++++++++++ 6 files changed, 52 insertions(+), 12 deletions(-) mode change 100755 => 100644 hutool-cron/src/test/java/cn/hutool/cron/TaskTableTest.java 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..84ac39a8f 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 @@ -35,7 +35,6 @@ public class BoolArrayMatcher implements PartMatcher { } this.minValue = min; } - @Override public boolean match(Integer value) { if (null == value || value >= bValues.length) { 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..03297001f 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,21 @@ public class DayOfMonthMatcher extends BoolArrayMatcher { return value == Month.getLastDay(month - 1, isLeapYear); } + public boolean isLast() { return match(31); } + /** + * 检查value是这个月的最后一天 + * @param value 被检查的值 + * @return + */ + public boolean isLastDay(Integer value,Integer month, boolean isLeapYear) { + if(isLastDayOfMonth(value, month, isLeapYear)) { + return match(31); + } + 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..30050727f 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,9 +192,9 @@ public class PatternMatcher { // pr#1189 if (i == Part.DAY_OF_MONTH.ordinal() && matchers[i] instanceof DayOfMonthMatcher - && ((DayOfMonthMatcher) matchers[i]).isLast()) { - int newMonth = newValues[Part.MONTH.ordinal()]; - int newYear = newValues[Part.YEAR.ordinal()]; + && ((DayOfMonthMatcher) matchers[i]).isLastDay(values[i],values[i+1],isLeapYear(values[Part.YEAR.ordinal()]))) { + int newMonth = values[Part.MONTH.ordinal()]; + int newYear = values[Part.YEAR.ordinal()]; nextValue = getLastDay(newMonth, newYear); } else { nextValue = matchers[i].nextAfter(values[i]); @@ -226,9 +226,9 @@ public class PatternMatcher { continue; } else if (i == Part.DAY_OF_MONTH.ordinal() && matchers[i] instanceof DayOfMonthMatcher - && ((DayOfMonthMatcher) matchers[i]).isLast()) { - int newMonth = newValues[Part.MONTH.ordinal()]; - int newYear = newValues[Part.YEAR.ordinal()]; + && ((DayOfMonthMatcher) matchers[i]).isLastDay(values[i],values[i+1],isLeapYear(values[Part.YEAR.ordinal()]))) { + int newMonth = values[Part.MONTH.ordinal()]; + int newYear = values[Part.YEAR.ordinal()]; nextValue = getLastDay(newMonth, newYear); } else { nextValue = matchers[i].nextAfter(values[i] + 1); @@ -247,6 +247,14 @@ public class PatternMatcher { return newValues; } + /** + * 判断年份是否是闰年 + * @param year + * @return 返回boolean表示是否是闰年 + */ + private static boolean isLeapYear(int year) { + return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); + } /** * 设置从{@link Part#SECOND}到指定部分,全部设置为最小值 * diff --git a/hutool-cron/src/test/java/cn/hutool/cron/TaskTableTest.java b/hutool-cron/src/test/java/cn/hutool/cron/TaskTableTest.java old mode 100755 new mode 100644 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 b119e38f5..04b0b985e 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 @@ -54,7 +54,7 @@ public class CronPatternNextMatchTest { // 时间正常递增 //noinspection ConstantConditions Calendar calendar = pattern.nextMatchAfter( - DateUtil.parse("2022-04-12 09:12:12").toCalendar()); + DateUtil.parse("2022-04-12 09:12:12").toCalendar()); assertTrue(pattern.match(calendar, true)); assertEquals("2022-04-12 09:12:23", DateUtil.date(calendar).toString()); @@ -62,28 +62,28 @@ public class CronPatternNextMatchTest { // 秒超出规定值的最大值,分+1,秒取最小值 //noinspection ConstantConditions calendar = pattern.nextMatchAfter( - DateUtil.parse("2022-04-12 09:09:24").toCalendar()); + DateUtil.parse("2022-04-12 09:09:24").toCalendar()); assertTrue(pattern.match(calendar, true)); assertEquals("2022-04-12 09:12:23", DateUtil.date(calendar).toString()); // 秒超出规定值的最大值,分不变,小时+1,秒和分使用最小值 //noinspection ConstantConditions calendar = pattern.nextMatchAfter( - DateUtil.parse("2022-04-12 09:12:24").toCalendar()); + DateUtil.parse("2022-04-12 09:12:24").toCalendar()); assertTrue(pattern.match(calendar, true)); assertEquals("2022-04-12 10:12:23", DateUtil.date(calendar).toString()); // 天超出规定值的最大值,月+1,天、时、分、秒取最小值 //noinspection ConstantConditions calendar = pattern.nextMatchAfter( - DateUtil.parse("2022-04-13 09:12:24").toCalendar()); + DateUtil.parse("2022-04-13 09:12:24").toCalendar()); assertTrue(pattern.match(calendar, true)); assertEquals("2022-05-12 00:12:23", DateUtil.date(calendar).toString()); // 跨年 //noinspection ConstantConditions calendar = pattern.nextMatchAfter( - DateUtil.parse("2021-12-22 00:00:00").toCalendar()); + DateUtil.parse("2021-12-22 00:00:00").toCalendar()); assertTrue(pattern.match(calendar, true)); assertEquals("2022-01-12 00:12:23", DateUtil.date(calendar).toString()); } 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); + } +}