修复cron中在小月时使用“L”的计算问题

This commit is contained in:
Looly 2024-03-29 11:22:56 +08:00
parent bdaa89fbd0
commit 74226c4f5e
4 changed files with 19 additions and 17 deletions

View File

@ -2,7 +2,7 @@
# 🚀Changelog # 🚀Changelog
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
# 5.8.27(2024-03-28) # 5.8.27(2024-03-29)
### 🐣新特性 ### 🐣新特性
* 【extra 】 FreemarkerEngine修改默认版本参数 * 【extra 】 FreemarkerEngine修改默认版本参数
@ -22,6 +22,7 @@
* 【captcha】 修复Graphics2D的资源没释放问题issue#I98PYN@Gitee * 【captcha】 修复Graphics2D的资源没释放问题issue#I98PYN@Gitee
* 【core 】 修复ClassUtil.getTypeArgument() 获取泛型存在null问题issue#3516@Github * 【core 】 修复ClassUtil.getTypeArgument() 获取泛型存在null问题issue#3516@Github
* 【core 】 修复图片操作未调用flush导致资源未释放问题issue#I9C7NA@Gitee * 【core 】 修复图片操作未调用flush导致资源未释放问题issue#I9C7NA@Gitee
* 【cron 】 修复cron中在小月时使用“L”的计算问题pr#1189@Gitee
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
# 5.8.26(2024-02-10) # 5.8.26(2024-02-10)

View File

@ -11,19 +11,13 @@ import java.util.List;
* @author Looly * @author Looly
*/ */
public class DayOfMonthMatcher extends BoolArrayMatcher { public class DayOfMonthMatcher extends BoolArrayMatcher {
/**
* 是否是查询最后一天L
*/
private final boolean isLast;
/** /**
* 构造 * 构造
* *
* @param intValueList 匹配的日值 * @param intValueList 匹配的日值
*/ */
public DayOfMonthMatcher(List<Integer> intValueList, boolean isLast) { public DayOfMonthMatcher(List<Integer> intValueList) {
super(intValueList); super(intValueList);
this.isLast = isLast;
} }
/** /**
@ -57,7 +51,7 @@ public class DayOfMonthMatcher extends BoolArrayMatcher {
} }
public boolean isLast() { public boolean isLast() {
return isLast; return match(31);
} }
} }

View File

@ -6,6 +6,7 @@ import cn.hutool.cron.pattern.Part;
import java.time.Year; import java.time.Year;
import java.util.Calendar; import java.util.Calendar;
import java.util.Objects;
import java.util.TimeZone; import java.util.TimeZone;
/** /**
@ -186,15 +187,19 @@ public class PatternMatcher {
// 周不参与计算 // 周不参与计算
i--; i--;
continue; continue;
} else if (i == Part.DAY_OF_MONTH.ordinal() }
// pr#1189
if (i == Part.DAY_OF_MONTH.ordinal()
&& matchers[i] instanceof DayOfMonthMatcher && matchers[i] instanceof DayOfMonthMatcher
&& ((DayOfMonthMatcher) matchers[i]).isLast()) { && ((DayOfMonthMatcher) matchers[i]).isLast()) {
int newMonth = newValues[Part.MONTH.ordinal()]; int newMonth = newValues[Part.MONTH.ordinal()];
int newYear = newValues[Part.YEAR.ordinal()]; int newYear = newValues[Part.YEAR.ordinal()];
nextValue = Month.of(newMonth - 1).getLastDay(DateUtil.isLeapYear(newYear)); nextValue = getLastDay(newMonth, newYear);
} else { } else {
nextValue = matchers[i].nextAfter(values[i]); nextValue = matchers[i].nextAfter(values[i]);
} }
if (nextValue > values[i]) { if (nextValue > values[i]) {
// 此部分正常获取新值结束循环后续的部分置最小值 // 此部分正常获取新值结束循环后续的部分置最小值
newValues[i] = nextValue; newValues[i] = nextValue;
@ -224,7 +229,7 @@ public class PatternMatcher {
&& ((DayOfMonthMatcher) matchers[i]).isLast()) { && ((DayOfMonthMatcher) matchers[i]).isLast()) {
int newMonth = newValues[Part.MONTH.ordinal()]; int newMonth = newValues[Part.MONTH.ordinal()];
int newYear = newValues[Part.YEAR.ordinal()]; int newYear = newValues[Part.YEAR.ordinal()];
nextValue = Month.of(newMonth - 1).getLastDay(DateUtil.isLeapYear(newYear)); nextValue = getLastDay(newMonth, newYear);
} else { } else {
nextValue = matchers[i].nextAfter(values[i] + 1); nextValue = matchers[i].nextAfter(values[i] + 1);
} }
@ -257,7 +262,7 @@ public class PatternMatcher {
&& ((DayOfMonthMatcher) get(part)).isLast()) { && ((DayOfMonthMatcher) get(part)).isLast()) {
int newMonth = values[Part.MONTH.ordinal()]; int newMonth = values[Part.MONTH.ordinal()];
int newYear = values[Part.YEAR.ordinal()]; int newYear = values[Part.YEAR.ordinal()];
values[i] = Month.of(newMonth - 1).getLastDay(DateUtil.isLeapYear(newYear)); values[i] = getLastDay(newMonth, newYear);
} else { } else {
values[i] = getMin(part); values[i] = getMin(part);
} }
@ -311,4 +316,9 @@ public class PatternMatcher {
//Console.log("Set [{}] as [{}]", part, value); //Console.log("Set [{}] as [{}]", part, value);
return calendar; return calendar;
} }
private static int getLastDay(int monthBase1, int year){
return Objects.requireNonNull(Month.of(monthBase1 - 1))
.getLastDay(DateUtil.isLeapYear(year));
}
} }

View File

@ -65,12 +65,9 @@ public class PartParser {
*/ */
public PartMatcher parse(String value) { public PartMatcher parse(String value) {
// 是否是查询最后一天 // 是否是查询最后一天
boolean isLastDay = false;
if (isMatchAllStr(value)) { if (isMatchAllStr(value)) {
//兼容Quartz的"?"表达式不会出现互斥情况"*"作用相同 //兼容Quartz的"?"表达式不会出现互斥情况"*"作用相同
return new AlwaysTrueMatcher(); return new AlwaysTrueMatcher();
} else if ("L".equalsIgnoreCase(value)) {
isLastDay = true;
} }
final List<Integer> values = parseArray(value); final List<Integer> values = parseArray(value);
@ -80,7 +77,7 @@ public class PartParser {
switch (this.part) { switch (this.part) {
case DAY_OF_MONTH: case DAY_OF_MONTH:
return new DayOfMonthMatcher(values, isLastDay); return new DayOfMonthMatcher(values);
case YEAR: case YEAR:
return new YearValueMatcher(values); return new YearValueMatcher(values);
default: default: