From 2c399fd72aa2e3a565f8682fe373708c02b1b29e Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 14 Apr 2022 01:16:59 +0800 Subject: [PATCH] fix next bug --- .../cn/hutool/cron/pattern/CronPattern.java | 14 ++++++++++---- .../cron/pattern/matcher/PatternMatcher.java | 19 +++++++++++++++---- .../pattern/CronPatternNextMatchTest.java | 5 +++-- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/hutool-cron/src/main/java/cn/hutool/cron/pattern/CronPattern.java b/hutool-cron/src/main/java/cn/hutool/cron/pattern/CronPattern.java index 85b2b7833..5c0e7cffd 100644 --- a/hutool-cron/src/main/java/cn/hutool/cron/pattern/CronPattern.java +++ b/hutool-cron/src/main/java/cn/hutool/cron/pattern/CronPattern.java @@ -1,6 +1,7 @@ package cn.hutool.cron.pattern; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.CalendarUtil; import cn.hutool.cron.pattern.matcher.PatternMatcher; import cn.hutool.cron.pattern.parser.PatternParser; @@ -129,14 +130,19 @@ public class CronPattern { } /** - * 返回匹配到的下一个时间
- * TODO 周定义后,结果错误,需改进 + * 返回匹配到的下一个时间 * * @param calendar 时间 * @return 匹配到的下一个时间 */ public Calendar nextMatchAfter(Calendar calendar) { - return nextMatchAfter(PatternUtil.getFields(calendar, true), calendar.getTimeZone()); + Calendar next = nextMatchAfter(PatternUtil.getFields(calendar, true), calendar.getTimeZone()); + if(false == match(next, true)){ + next.set(Calendar.DAY_OF_MONTH, next.get(Calendar.DAY_OF_MONTH) + 1); + next = CalendarUtil.beginOfDay(next); + return nextMatchAfter(next); + } + return next; } @Override @@ -152,7 +158,7 @@ public class CronPattern { */ private boolean match(int[] fields) { for (PatternMatcher matcher : matchers) { - if (matcher.match(fields[0], fields[1], fields[2], fields[3], fields[4], fields[5], fields[6])) { + if (matcher.match(fields)) { return true; } } 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 b099ce3f1..908154e9b 100644 --- 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 @@ -62,6 +62,16 @@ public class PatternMatcher { //region match + /** + * 给定时间是否匹配定时任务表达式 + * + * @param fields 时间字段值,{second, minute, hour, dayOfMonth, month, dayOfWeek, year} + * @return 如果匹配返回 {@code true}, 否则返回 {@code false} + */ + public boolean match(int[] fields) { + return match(fields[0], fields[1], fields[2], fields[3], fields[4], fields[5], fields[6]); + } + /** * 给定时间是否匹配定时任务表达式 * @@ -74,7 +84,7 @@ public class PatternMatcher { * @param year 年 * @return 如果匹配返回 {@code true}, 否则返回 {@code false} */ - public boolean match(int second, int minute, int hour, int dayOfMonth, int month, int dayOfWeek, int year) { + private boolean match(int second, int minute, int hour, int dayOfMonth, int month, int dayOfWeek, int year) { return ((second < 0) || matchers[0].match(second)) // 匹配秒(非秒匹配模式下始终返回true) && matchers[1].match(minute)// 匹配分 && matchers[2].match(hour)// 匹配时 @@ -127,10 +137,11 @@ public class PatternMatcher { final int[] newValues = nextMatchValuesAfter(values); for (int i = 0; i < newValues.length; i++) { // 周无需设置 - if(i != Part.DAY_OF_WEEK.ordinal()){ + if (i != Part.DAY_OF_WEEK.ordinal()) { setValue(calendar, Part.of(i), newValues[i]); } } + return calendar; } @@ -158,7 +169,7 @@ public class PatternMatcher { // 新值,-1表示标识为回退 int nextValue = 0; while (i >= 0) { - if(i == Part.DAY_OF_WEEK.ordinal()){ + if (i == Part.DAY_OF_WEEK.ordinal()) { // 周不参与计算 i--; continue; @@ -182,7 +193,7 @@ public class PatternMatcher { // 值产生回退,向上查找变更值 if (-1 == nextValue) { while (i <= Part.YEAR.ordinal()) { - if(i == Part.DAY_OF_WEEK.ordinal()){ + if (i == Part.DAY_OF_WEEK.ordinal()) { // 周不参与计算 i++; continue; 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 63fcf7a3d..59f39cfbd 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 @@ -91,9 +91,10 @@ public class CronPatternNextMatchTest { @Test public void nextMatchAfterByWeekTest(){ CronPattern pattern = new CronPattern("1 1 1 * * Sat *"); - // 周五 - final DateTime time = DateUtil.parse("2022-04-01"); + // 周日,下个周六在4月9日 + final DateTime time = DateUtil.parse("2022-04-03"); assert time != null; final Calendar calendar = pattern.nextMatchAfter(time.toCalendar()); + Assert.assertEquals("2022-04-09 01:01:01", DateUtil.date(calendar).toString()); } }