TL;博士
在 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 的文档中没有找到该年份的最大值)。可能有一种更清洁的方法可以做到这一点,但这将满足我现在的需求。
所以,最后,我建议的 cron 是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 的解决方案时忘记的部分,使我成为傻瓜并证明我的测试不是我的证明。