3.9K Star 22.7K Fork 7.8K

GVPdromara / hutool

 / 详情

CronPattern#nextMatchAfter死循环

已完成
创建于  
2024-02-20 19:43

版本情况

JDK版本: openjdk_8_382
hutool版本: 5.8.27-SNAPSHOT

问题描述(包括截图)

cron:0 0 0 L 2 ?
当指定小月的最后一天时,计算下次时间就会死循环。
里面实现有点复杂,未想到怎么修复,还是大佬们来吧。。。

  1. 复现代码
	@Test
	public void testNextMatchAfter() {
		// 匹配所有月,返回下一月
		DateTime date = DateUtil.parse("2022-04-08 07:44:16");
		CronPattern pattern = new CronPattern("0 0 0 L 2 ?");
		//noinspection ConstantConditions
		Calendar calendar = pattern.nextMatchAfter(date.toCalendar());
		System.out.println(DateUtil.date(calendar));
	}
  1. 堆栈信息
java.lang.StackOverflowError
	at sun.util.calendar.ZoneInfo.getOffsets(ZoneInfo.java:236)
	at java.util.GregorianCalendar.computeFields(GregorianCalendar.java:2336)
	at java.util.GregorianCalendar.computeFields(GregorianCalendar.java:2308)
	at java.util.Calendar.setTimeInMillis(Calendar.java:1804)
	at java.util.Calendar$Builder.build(Calendar.java:1508)
	at sun.util.locale.provider.CalendarProviderImpl.getInstance(CalendarProviderImpl.java:88)
	at java.util.Calendar.createCalendar(Calendar.java:1666)
	at java.util.Calendar.getInstance(Calendar.java:1627)
	at cn.hutool.cron.pattern.matcher.PatternMatcher.nextMatchAfter(PatternMatcher.java:145)
	at cn.hutool.cron.pattern.CronPattern.nextMatchAfter(CronPattern.java:191)
	at cn.hutool.cron.pattern.CronPattern.nextMatchAfter(CronPattern.java:152)
	at cn.hutool.cron.pattern.CronPattern.nextMatchAfter(CronPattern.java:156)
	at cn.hutool.cron.pattern.CronPattern.nextMatchAfter(CronPattern.java:156)
	at cn.hutool.cron.pattern.CronPattern.nextMatchAfter(CronPattern.java:156)
  1. 测试涉及到的文件(注意脱密)
    输入图片说明

评论 (4)

Addyu 创建了任务

DayOfMonthMatcher使用31就表示最后一天,实际有歧义。不好兼容了。感觉得重构下,可参考quartz的CronExpression实现。

确实是有问题,有31天的大月都正常,其他月份都有问题。

CherryRum 添加了
 
bug
标签
Looly 修改了描述

看了源码,个人浅解有两种,如果不对,欢迎指正:
第一种:
枚举里面初始化不用改,因为这个枚举不改,初始化的BoolArrayMatcher里面也不用改;
以上两点不改,那就在具体用的时候改:setToMin()方法,最后for循环把values[]数组填满之后,加一行修改的代码,
或者当part="MONTH"的时候,处理values[i-1]的值;
第二种:
在public PatternMatcher构造器中,处理PartMatcher[] matchers的时候,顺便根据入参的PartMatcher monthMatcher把PartMatcher dayOfMonthMatcher重新覆盖一遍。
以上是我随机在gitee找到这个项目,然后进来看见这个bug,花了两三个小时看了一下源码的理解,如果不正确欢迎指正 :joy:

可以试着修改下,跑得过单测可以提mr给大佬们合并的。我用了几种方法包括你说的两种思路,没改明白。 :joy:

emptypoint 通过dromara/hutool Pull Request !1189任务状态待办的 修改为已完成
Looly 任务状态已完成 修改为进行中
Looly 任务状态进行中 修改为已完成

登录 后才可以发表评论

状态
负责人
里程碑
Pull Requests
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
开始日期   -   截止日期
-
置顶选项
优先级
参与者(3)
2311405 addyu 1696643720
Java
1
https://gitee.com/dromara/hutool.git
git@gitee.com:dromara/hutool.git
dromara
hutool
hutool

搜索帮助

344bd9b3 5694891 D2dac590 5694891