From 4c00f6adb22a005cfa958c4d3c4e55ef70ec5f75 Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 8 Aug 2024 19:15:24 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DCronPatternUtil.nextDateAfter?= =?UTF-8?q?=E6=A0=88=E6=BA=A2=E5=87=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + .../cn/hutool/cron/pattern/CronPattern.java | 22 +++++++++++---- .../hutool/cron/pattern/CronPatternUtil.java | 14 ++++++++++ .../cn/hutool/cron/pattern/Issue3685Test.java | 28 +++++++++++++++++++ 4 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 hutool-cron/src/test/java/cn/hutool/cron/pattern/Issue3685Test.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 7474d81b4..2fe036d9a 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ * 【core 】 修复CsvParser中对正文中双引号处理逻辑问题(pr#1244@Gitee) * 【core 】 修复ZipUtil.zip压缩到本目录时可能造成的死循环问题(issue#IAGYDG@Gitee) * 【cache 】 修复AbstractCache.get中锁不一致导致的并发问题(issue#3686@Github) +* 【cron 】 修复CronPatternUtil.nextDateAfter栈溢出问题(issue#3685@Github) ------------------------------------------------------------------------------------------------------------- # 5.8.29(2024-07-03) 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 6dfb4633c..1c80205d3 100755 --- a/hutool-cron/src/main/java/cn/hutool/cron/pattern/CronPattern.java +++ b/hutool-cron/src/main/java/cn/hutool/cron/pattern/CronPattern.java @@ -156,13 +156,25 @@ public class CronPattern { calendar = newCalendar; } + return nextMatch(calendar); + } + + /** + * 返回匹配到的下一个时间,如果给定时间匹配,直接返回 + * + * @param calendar 时间 + * @return 匹配到的下一个时间 + * @since 5.8.30 + */ + public Calendar nextMatch(final Calendar calendar) { 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); + if (match(next, true)) { + return next; } - return next; + + next.set(Calendar.DAY_OF_MONTH, next.get(Calendar.DAY_OF_MONTH) + 1); + next = CalendarUtil.beginOfDay(next); + return nextMatch(next); } @Override diff --git a/hutool-cron/src/main/java/cn/hutool/cron/pattern/CronPatternUtil.java b/hutool-cron/src/main/java/cn/hutool/cron/pattern/CronPatternUtil.java index d91762d76..cd52b2274 100755 --- a/hutool-cron/src/main/java/cn/hutool/cron/pattern/CronPatternUtil.java +++ b/hutool-cron/src/main/java/cn/hutool/cron/pattern/CronPatternUtil.java @@ -17,6 +17,18 @@ import java.util.List; */ public class CronPatternUtil { + /** + * 列举指定日期之后内第一个匹配表达式的日期 + * + * @param pattern 表达式 + * @param start 起始时间 + * @return 日期 + * @since 5.8.30 + */ + public static Date nextDateAfter(CronPattern pattern, Date start) { + return DateUtil.date(pattern.nextMatchAfter(CalendarUtil.calendar(start))); + } + /** * 列举指定日期之后内第一个匹配表达式的日期 * @@ -25,7 +37,9 @@ public class CronPatternUtil { * @param isMatchSecond 是否匹配秒(无效) * @return 日期 * @since 4.5.8 + * @deprecated isMatchSecond无效,使用 {@link #nextDateAfter(CronPattern, Date)} */ + @Deprecated public static Date nextDateAfter(CronPattern pattern, Date start, boolean isMatchSecond) { return DateUtil.date(pattern.nextMatchAfter(CalendarUtil.calendar(start))); } diff --git a/hutool-cron/src/test/java/cn/hutool/cron/pattern/Issue3685Test.java b/hutool-cron/src/test/java/cn/hutool/cron/pattern/Issue3685Test.java new file mode 100644 index 000000000..0675d2acc --- /dev/null +++ b/hutool-cron/src/test/java/cn/hutool/cron/pattern/Issue3685Test.java @@ -0,0 +1,28 @@ +package cn.hutool.cron.pattern; + +import cn.hutool.core.date.DateUtil; +import org.junit.Test; + +import java.util.Date; + +import static org.junit.Assert.assertEquals; + +public class Issue3685Test { + @Test + public void nextDateAfterTest() { + Date date = CronPatternUtil.nextDateAfter(CronPattern.of("0 0 * * MON"), DateUtil.parse("2024-08-01")); + assertEquals("2024-08-05 00:00:00", date.toString()); + + date = CronPatternUtil.nextDateAfter(CronPattern.of("0 0 * * MON"), DateUtil.parse("2024-08-02")); + assertEquals("2024-08-05 00:00:00", date.toString()); + + date = CronPatternUtil.nextDateAfter(CronPattern.of("0 0 * * MON"), DateUtil.parse("2024-08-03")); + assertEquals("2024-08-05 00:00:00", date.toString()); + + date = CronPatternUtil.nextDateAfter(CronPattern.of("0 0 * * MON"), DateUtil.parse("2024-08-04")); + assertEquals("2024-08-05 00:00:00", date.toString()); + + date = CronPatternUtil.nextDateAfter(CronPattern.of("0 0 * * MON"), DateUtil.parse("2024-08-05")); + assertEquals("2024-08-12 00:00:00", date.toString()); + } +}