diff --git a/hutool-core/src/main/java/cn/hutool/v7/core/annotation/AnnotationUtil.java b/hutool-core/src/main/java/cn/hutool/v7/core/annotation/AnnotationUtil.java index 4fe4ef63c..5d87a91fb 100644 --- a/hutool-core/src/main/java/cn/hutool/v7/core/annotation/AnnotationUtil.java +++ b/hutool-core/src/main/java/cn/hutool/v7/core/annotation/AnnotationUtil.java @@ -97,7 +97,12 @@ public class AnnotationUtil { // region ----- getAnnotation /** - * 获取直接声明的注解,若已有缓存则从缓存中获取 + * 获取直接声明的注解,若已有缓存则从缓存中获取,主要为: + * * * @param element {@link AnnotatedElement} * @return 注解 @@ -108,7 +113,12 @@ public class AnnotationUtil { } /** - * 获取指定注解 + * 获取指定注解,主要为: + * * * @param annotationEle {@link AnnotatedElement},可以是Class、Method、Field、Constructor、ReflectPermission * @param isToCombination 是否为转换为组合注解,组合注解可以递归获取注解的注解 diff --git a/hutool-core/src/main/java/cn/hutool/v7/core/annotation/elements/HierarchicalAnnotatedElements.java b/hutool-core/src/main/java/cn/hutool/v7/core/annotation/elements/HierarchicalAnnotatedElements.java index 29992ae95..ef8755118 100644 --- a/hutool-core/src/main/java/cn/hutool/v7/core/annotation/elements/HierarchicalAnnotatedElements.java +++ b/hutool-core/src/main/java/cn/hutool/v7/core/annotation/elements/HierarchicalAnnotatedElements.java @@ -342,8 +342,7 @@ public class HierarchicalAnnotatedElements implements AnnotatedElement, Iterable scanHierarchy(mappings, (Class)source, false, source); } // 原始元素是方法 - else if (source instanceof Method) { - final Method methodSource = (Method)source; + else if (source instanceof final Method methodSource) { // 静态、私有与被final关键字修饰方法无法被子类重写,因此不可能具有层级结构 if (Modifier.isPrivate(methodSource.getModifiers()) || Modifier.isFinal(methodSource.getModifiers()) diff --git a/hutool-core/src/main/java/cn/hutool/v7/core/date/Month.java b/hutool-core/src/main/java/cn/hutool/v7/core/date/Month.java index 64e2c9251..28f494a3e 100644 --- a/hutool-core/src/main/java/cn/hutool/v7/core/date/Month.java +++ b/hutool-core/src/main/java/cn/hutool/v7/core/date/Month.java @@ -276,14 +276,14 @@ public enum Month { /** * 获得指定月的最后一天 * - * @param month 月份,从0开始 + * @param monthBase0 月份,从0开始 * @param isLeapYear 是否为闰年,闰年只对二月有影响 * @return 最后一天,可能为28,29,30,31 * @since 5.4.7 */ - public static int getLastDay(final int month, final boolean isLeapYear) { - final Month of = of(month); - Assert.notNull(of, "Invalid Month base 0: " + month); + public static int getLastDay(final int monthBase0, final boolean isLeapYear) { + final Month of = of(monthBase0); + Assert.notNull(of, "Invalid Month base 0: " + monthBase0); return of.getLastDay(isLeapYear); } diff --git a/hutool-cron/src/main/java/cn/hutool/v7/cron/pattern/CronPattern.java b/hutool-cron/src/main/java/cn/hutool/v7/cron/pattern/CronPattern.java index 4a2b07721..484618813 100644 --- a/hutool-cron/src/main/java/cn/hutool/v7/cron/pattern/CronPattern.java +++ b/hutool-cron/src/main/java/cn/hutool/v7/cron/pattern/CronPattern.java @@ -18,6 +18,7 @@ package cn.hutool.v7.cron.pattern; import cn.hutool.v7.core.comparator.CompareUtil; import cn.hutool.v7.core.date.CalendarUtil; +import cn.hutool.v7.core.lang.Console; import cn.hutool.v7.cron.pattern.matcher.PatternMatcher; import cn.hutool.v7.cron.pattern.parser.PatternParser; diff --git a/hutool-cron/src/main/java/cn/hutool/v7/cron/pattern/matcher/DayOfMonthMatcher.java b/hutool-cron/src/main/java/cn/hutool/v7/cron/pattern/matcher/DayOfMonthMatcher.java index 77f826860..6a0b33fab 100644 --- a/hutool-cron/src/main/java/cn/hutool/v7/cron/pattern/matcher/DayOfMonthMatcher.java +++ b/hutool-cron/src/main/java/cn/hutool/v7/cron/pattern/matcher/DayOfMonthMatcher.java @@ -40,7 +40,7 @@ public class DayOfMonthMatcher extends BoolArrayMatcher { /** * 给定的日期是否匹配当前匹配器 * - * @param value 被检查的值,此处为日 + * @param value 被检查的值,此处为日,从1开始 * @param month 实际的月份,从1开始 * @param isLeapYear 是否闰年 * @return 是否匹配 diff --git a/hutool-cron/src/main/java/cn/hutool/v7/cron/pattern/matcher/PatternMatcher.java b/hutool-cron/src/main/java/cn/hutool/v7/cron/pattern/matcher/PatternMatcher.java index 32f4de559..e4e84f977 100644 --- a/hutool-cron/src/main/java/cn/hutool/v7/cron/pattern/matcher/PatternMatcher.java +++ b/hutool-cron/src/main/java/cn/hutool/v7/cron/pattern/matcher/PatternMatcher.java @@ -17,10 +17,10 @@ package cn.hutool.v7.cron.pattern.matcher; import cn.hutool.v7.core.date.DateUtil; +import cn.hutool.v7.core.text.StrUtil; import cn.hutool.v7.cron.pattern.Part; import java.time.Year; -import java.util.Arrays; import java.util.Calendar; import java.util.TimeZone; @@ -177,9 +177,15 @@ public class PatternMatcher { @Override public String toString() { - return "PatternMatcher{" + - "matchers=" + Arrays.toString(matchers) + - '}'; + return StrUtil.format(""" + SECOND : {} + MINUTE : {} + HOUR : {} + DAY_OF_MONTH: {} + MONTH : {} + DAY_OF_WEEK : {} + YEAR : {} + """, (Object[]) this.matchers); } /** diff --git a/hutool-cron/src/main/java/cn/hutool/v7/cron/pattern/matcher/YearValueMatcher.java b/hutool-cron/src/main/java/cn/hutool/v7/cron/pattern/matcher/YearValueMatcher.java index fdb30b7fe..6ea11c5aa 100644 --- a/hutool-cron/src/main/java/cn/hutool/v7/cron/pattern/matcher/YearValueMatcher.java +++ b/hutool-cron/src/main/java/cn/hutool/v7/cron/pattern/matcher/YearValueMatcher.java @@ -29,6 +29,11 @@ public class YearValueMatcher implements PartMatcher { private final LinkedHashSet valueList; + /** + * 构造 + * + * @param intValueList 年数字列表 + */ public YearValueMatcher(final Collection intValueList) { this.valueList = new LinkedHashSet<>(intValueList); } @@ -49,4 +54,11 @@ public class YearValueMatcher implements PartMatcher { // 年无效,此表达式整体无效 return -1; } + + @Override + public String toString() { + return "YearValueMatcher{" + + "valueList=" + valueList + + '}'; + } } diff --git a/hutool-cron/src/main/java/cn/hutool/v7/cron/pattern/parser/PartParser.java b/hutool-cron/src/main/java/cn/hutool/v7/cron/pattern/parser/PartParser.java index 3f2ab04c3..bd7400058 100644 --- a/hutool-cron/src/main/java/cn/hutool/v7/cron/pattern/parser/PartParser.java +++ b/hutool-cron/src/main/java/cn/hutool/v7/cron/pattern/parser/PartParser.java @@ -91,14 +91,11 @@ public class PartParser { throw new CronException("Invalid part value: [{}]", value); } - switch (this.part) { - case DAY_OF_MONTH: - return new DayOfMonthMatcher(values); - case YEAR: - return new YearValueMatcher(values); - default: - return new BoolArrayMatcher(values); - } + return switch (this.part) { + case DAY_OF_MONTH -> new DayOfMonthMatcher(values); + case YEAR -> new YearValueMatcher(values); + default -> new BoolArrayMatcher(values); + }; } /** @@ -163,6 +160,7 @@ public class PartParser { *
  • 8-3
  • *
  • 3-3
  • * + * 其中"*"解析时按照min值处理 * * @param value 范围表达式 * @param step 步进 @@ -287,15 +285,15 @@ public class PartParser { return part.getMax(); } - switch (this.part) { - case MONTH: + return switch (this.part) { + case MONTH -> // 月份从1开始 - return Month.of(name).getValueBaseOne(); - case DAY_OF_WEEK: + Month.of(name).getValueBaseOne(); + case DAY_OF_WEEK -> // 周从0开始,0表示周日 - return Week.of(name).ordinal(); - } + Week.of(name).ordinal(); + default -> throw new CronException("Invalid alias value: [{}]", name); + }; - throw new CronException("Invalid alias value: [{}]", name); } } diff --git a/hutool-cron/src/test/java/cn/hutool/v7/cron/pattern/CronPatternUtilTest.java b/hutool-cron/src/test/java/cn/hutool/v7/cron/pattern/CronPatternUtilTest.java index 0736d1fb3..b5b7594df 100644 --- a/hutool-cron/src/test/java/cn/hutool/v7/cron/pattern/CronPatternUtilTest.java +++ b/hutool-cron/src/test/java/cn/hutool/v7/cron/pattern/CronPatternUtilTest.java @@ -16,6 +16,7 @@ package cn.hutool.v7.cron.pattern; +import cn.hutool.v7.core.date.DateTime; import cn.hutool.v7.core.date.DateUtil; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -60,4 +61,28 @@ public class CronPatternUtilTest { Assertions.assertEquals("2018-10-31 03:00:00", matchedDates.get(3).toString()); Assertions.assertEquals("2018-10-31 04:00:00", matchedDates.get(4).toString()); } + + @Test + public void issue4056Test() { + // "*/5"和"1/5"意义相同,从1号开始,每5天一个匹配,则匹配的天为: + // 2025-02-01, 2025-02-06, 2025-02-11, 2025-02-16, 2025-02-21, 2025-02-26 + // 2025-02-28不应该在匹配之列 + final String cron = "0 0 0 */5 * ? *"; + final CronPattern cronPattern = new CronPattern(cron); + final boolean match = cronPattern.match(DateUtil.parse("2025-02-28 00:00:00").toCalendar(), true); + Assertions.assertFalse( match); + } + + @Test + public void issue4056Test2() { + final String cron = "0 0 0 */5 * ? *"; + final CronPattern cronPattern = new CronPattern(cron); + + final DateTime judgeTime = DateUtil.parse("2025-02-27 23:59:59"); + final Date nextDate = CronPatternUtil.nextDateAfter(cronPattern, judgeTime); + // "*/5"和"1/5"意义相同,从1号开始,每5天一个匹配,则匹配的天为: + // 2025-02-01, 2025-02-06, 2025-02-11, 2025-02-16, 2025-02-21, 2025-02-26 + // 下一个匹配日期应为2025-03-01 + Assertions.assertEquals("2025-03-01 00:00:00", nextDate.toString()); + } }