From 74226c4f5ebaceb604fe0f1e1da6ffbae28eaddf Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 29 Mar 2024 11:22:56 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dcron=E4=B8=AD=E5=9C=A8?= =?UTF-8?q?=E5=B0=8F=E6=9C=88=E6=97=B6=E4=BD=BF=E7=94=A8=E2=80=9CL?= =?UTF-8?q?=E2=80=9D=E7=9A=84=E8=AE=A1=E7=AE=97=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 3 ++- .../pattern/matcher/DayOfMonthMatcher.java | 10 ++-------- .../cron/pattern/matcher/PatternMatcher.java | 18 ++++++++++++++---- .../hutool/cron/pattern/parser/PartParser.java | 5 +---- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 377f7e4ce..69316ebbb 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.27(2024-03-28) +# 5.8.27(2024-03-29) ### 🐣新特性 * 【extra 】 FreemarkerEngine修改默认版本参数 @@ -22,6 +22,7 @@ * 【captcha】 修复Graphics2D的资源没释放问题(issue#I98PYN@Gitee) * 【core 】 修复ClassUtil.getTypeArgument() 获取泛型存在null问题(issue#3516@Github) * 【core 】 修复图片操作未调用flush导致资源未释放问题(issue#I9C7NA@Gitee) +* 【cron 】 修复cron中在小月时使用“L”的计算问题(pr#1189@Gitee) ------------------------------------------------------------------------------------------------------------- # 5.8.26(2024-02-10) 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 eeb631830..0ce10436c 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 @@ -11,19 +11,13 @@ import java.util.List; * @author Looly */ public class DayOfMonthMatcher extends BoolArrayMatcher { - /** - * 是否是查询最后一天,即“L” - */ - private final boolean isLast; - /** * 构造 * * @param intValueList 匹配的日值 */ - public DayOfMonthMatcher(List intValueList, boolean isLast) { + public DayOfMonthMatcher(List intValueList) { super(intValueList); - this.isLast = isLast; } /** @@ -57,7 +51,7 @@ public class DayOfMonthMatcher extends BoolArrayMatcher { } public boolean isLast() { - return isLast; + return match(31); } } 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 6a31ed319..65dfe6bec 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 @@ -6,6 +6,7 @@ import cn.hutool.cron.pattern.Part; import java.time.Year; import java.util.Calendar; +import java.util.Objects; import java.util.TimeZone; /** @@ -186,15 +187,19 @@ public class PatternMatcher { // 周不参与计算 i--; continue; - } else if (i == Part.DAY_OF_MONTH.ordinal() + } + + // 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()]; - nextValue = Month.of(newMonth - 1).getLastDay(DateUtil.isLeapYear(newYear)); + nextValue = getLastDay(newMonth, newYear); } else { nextValue = matchers[i].nextAfter(values[i]); } + if (nextValue > values[i]) { // 此部分正常获取新值,结束循环,后续的部分置最小值 newValues[i] = nextValue; @@ -224,7 +229,7 @@ public class PatternMatcher { && ((DayOfMonthMatcher) matchers[i]).isLast()) { int newMonth = newValues[Part.MONTH.ordinal()]; int newYear = newValues[Part.YEAR.ordinal()]; - nextValue = Month.of(newMonth - 1).getLastDay(DateUtil.isLeapYear(newYear)); + nextValue = getLastDay(newMonth, newYear); } else { nextValue = matchers[i].nextAfter(values[i] + 1); } @@ -257,7 +262,7 @@ public class PatternMatcher { && ((DayOfMonthMatcher) get(part)).isLast()) { int newMonth = values[Part.MONTH.ordinal()]; int newYear = values[Part.YEAR.ordinal()]; - values[i] = Month.of(newMonth - 1).getLastDay(DateUtil.isLeapYear(newYear)); + values[i] = getLastDay(newMonth, newYear); } else { values[i] = getMin(part); } @@ -311,4 +316,9 @@ public class PatternMatcher { //Console.log("Set [{}] as [{}]", part, value); return calendar; } + + private static int getLastDay(int monthBase1, int year){ + return Objects.requireNonNull(Month.of(monthBase1 - 1)) + .getLastDay(DateUtil.isLeapYear(year)); + } } diff --git a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/PartParser.java b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/PartParser.java index d80bf2736..99cb2e498 100644 --- a/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/PartParser.java +++ b/hutool-cron/src/main/java/cn/hutool/cron/pattern/parser/PartParser.java @@ -65,12 +65,9 @@ public class PartParser { */ public PartMatcher parse(String value) { // 是否是查询最后一天 - boolean isLastDay = false; if (isMatchAllStr(value)) { //兼容Quartz的"?"表达式,不会出现互斥情况,与"*"作用相同 return new AlwaysTrueMatcher(); - } else if ("L".equalsIgnoreCase(value)) { - isLastDay = true; } final List values = parseArray(value); @@ -80,7 +77,7 @@ public class PartParser { switch (this.part) { case DAY_OF_MONTH: - return new DayOfMonthMatcher(values, isLastDay); + return new DayOfMonthMatcher(values); case YEAR: return new YearValueMatcher(values); default: