TL; DR
在Quartz 1中,您可以使用以下cron :(59 59 23 31 12 ? 2099
最后一个有效日期)。
在Quartz 2中,您可以使用以下cron:0 0 0 1 1 ? 2200
将来使用表达式
使用进行了一些快速测试org.quartz.CronExpression
。
String exp = "0 0 0 1 1 ? 3000";
boolean valid = CronExpression.isValidExpression(exp);
System.out.println(valid);
if (valid) {
CronExpression cronExpression = new CronExpression(exp);
System.out.println(cronExpression.getNextValidTimeAfter(new Date()));
}
当我这样做时String exp = "# 0 0 0 1 1 ?";
,isValid
测试返回false
。
有了上面给出的示例,输出如下:
true
null
含义:
- 该表达式有效;
- 没有与该表达式匹配的即将到来的日期。
但是,要使调度程序接受cron触发器,后者必须与将来的日期匹配。
我尝试了几年,发现一旦年份超过2300,Quartz似乎就不再烦恼了(尽管我在Quartz 2的文档中没有提到该年份的最大值)。可能会有更清洁的方法来执行此操作,但这将满足我的需求。
因此,最后,我建议的时间表是0 0 0 1 1 ? 2200
。
石英1款
请注意,在Quartz 1中,2099是最后一个有效年份。因此,您可以调整cron表达式以使用Maciej Matys的建议:59 59 23 31 12 ? 2099
替代方法:使用过去的日期
Arnaud Denoyelle提出了一些更优雅的建议,上面的测试证明了这一点是正确的表达方式:与其选择一个较远的日期,不如选择一个较远的日期:
0 0 0 1 1 ? 1970
(根据Quartz文档的第一个有效表达式)。
但是此解决方案不起作用。
hippofluff强调说Quartz过去将检测到一个表达式,将不再执行,因此将引发异常。
org.quartz.SchedulerException: Based on configured schedule, the given trigger will never fire.
这似乎已经在Quartz很久了。
经验教训:测试不是万无一失的
这凸显了我的测试的弱点:如果要测试a CronExpression
,请记住它必须具有nextValidTime
1。否则,您将其传递给的调度程序将简单地拒绝它,并带有上述异常。
我建议修改测试代码如下:
String exp = "0 0 0 1 1 ? 3000";
boolean valid = CronExpression.isValidExpression(exp);
if (valid) {
CronExpression cronExpression = new CronExpression(exp);
valid = cronExpression.getNextValidTimeAfter(new Date()) != null;
}
System.out.println("Can I use <" + exp + ">? " + (valid ? "Go ahead!" : "This shall fail."));
到此为止:无需思考,只需阅读输出即可。
1这是我在测试Arnaud的解决方案时忘了的部分,这使我变得愚蠢,并证明我的测试不是靠我自己。
#
注释字符开始命令。