quartz定时器异常Support for specifying both a day-of-week AND a day-of-month parameter is not implemented
异常现象
使用quartz定时器解析部分cron表达式时,抛出ParseException异常:Support for specifying both a day-of-week AND a day-of-month parameter is not implemented
异常原因
该异常原因为:Quartz 对 “Day of Month” 和 “Day of Week” 字段的互斥原则,“日”(Day of Month)和“周几”(Day of Week)这两个字段不能同时使用 * 或具体值。即:
- 如果指定了 * 在“日”字段,那么“周几”字段应使用 ?
- 反之亦然:如果在“周几”用了 MON-FRI,那么“日”字段应该用 ? 来表示“不指定”
否则,Quartz 会认为存在 调度歧义(到底是按日还是按周?),从而抛出异常。
代码测试验证
import org.quartz.CronExpression;
public class CronTest {
public static void main(String[] args) {
String cron1 = "0 0 15 * * MON-FRI"; // ❌ 会失败
String cron2 = "0 0 15 ? * MON-FRI"; // ✅ 正确
try {
CronExpression.validateExpression(cron1);
System.out.println("cron1 is valid");
} catch (Exception e) {
System.out.println("cron1 invalid: " + e.getMessage());// ❌ 异常输出
}
try {
CronExpression.validateExpression(cron2);
System.out.println("cron2 is valid"); // ✅ 正常输出
} catch (Exception e) {
System.out.println("cron2 invalid: " + e.getMessage());
}
}
}
Quartz 中的最佳实践
//推荐写法:使用 ? 表示“日”字段不参与调度
0 13,53 15 ? * MON-FRI
//或者更明确地加上年(可选)
0 13,53 15 ? * MON-FRI *
Quartz Cron 表达式格式说明
Quartz 使用的是 7 个字段 的 Cron 表达式格式(与标准 Unix cron 不同):
| 字段 | 允许值 | 是否必需 | 示例 |
|---|---|---|---|
| 秒(Seconds) | 0-59 | 是 | 0 |
| 分钟(Minutes) | 0-59 | 是 | 0 |
| 小时(Hours) | 0-23 | 是 | 15 |
| 日(Day of Month) | 1-31 | 是 | * |
| 月(Month) | 1-12 | 是 | * |
| 周几(Day of Week) | 1-7 或 SUN-SAT | 是 | MON-FRI |
| 年(Year) | 1970-2099(可选) | 否 | * 或省略 |
⚠️ 注意:Quartz 支持 6 位或 7 位格式。如果省略第 7 位(年),默认为 *。
常见 Quartz Cron 示例
1. 每分钟执行一次
0 0/1 * * * ?
解释:每分钟的第 0 秒触发
2. 每5分钟执行一次
0 */5 * * * ?
或等价写法:
0 0,5,10,15,20,25,30,35,40,45,50,55 * * * ?
3. 每小时整点执行
0 0 * * * ?
每小时第 0 分钟、第 0 秒执行
4. 每天凌晨2点执行
0 0 2 * * ?
✅ 推荐:使用
?在“日”或“周几”字段之一
5. 每天中午12点执行
0 0 12 * * ?
6. 每月1号凌晨1点执行
0 0 1 1 * ?
7. 每月最后一天执行(不精确)
0 0 0 L * ?
L= Last day of month
⚠️ 注意:L不支持所有场景,建议结合代码判断更准确
8. 每月最后一个周五
0 0 0 ? * 6L
6L= 本月最后一个星期五(6=Fri)
9. 每月第三个周一
0 0 0 ? * 2#3
2#3= 第三个周一(2=Mon,#3=第3个)
10. 工作日(周一至周五)上午9点执行
0 0 9 ? * MON-FRI
✅ 推荐写法:使用
?表示“日”字段不参与调度
11. 周六和周日上午10点执行
0 0 10 ? * SAT,SUN
或写成:
0 0 10 ? * 7,1
12. 每季度第一天凌晨0点(如 1月1日、4月1日等)
0 0 0 1 1,4,7,10 ?
手动列出每个季度的第一个月
13. 每年1月1日零点执行
0 0 0 1 1 ?
14. 每个工作日的上午8点到下午6点,每两小时执行一次
0 0 8-18/2 ? * MON-FRI
8-18/2= 从8点到18点,每隔2小时一次 → 8,10,12,14,16,18 点
15. 每30秒执行一次
0/30 * * * * ?
0/30= 从第0秒开始,每30秒一次(即 :00 和 :30)
16. 上午9:15执行一次
0 15 9 * * ?
17. 每周二晚上8点执行
0 0 20 ? * TUE
或:
0 0 20 ? * 3
18. 每月第一个周六
0 0 0 ? * SAT#1
SAT#1= 第一个周六
19. 每两月执行一次(如奇数月1号)
0 0 0 1 1/2 ?
1/2= 从1月开始,每隔2个月 → 1,3,5,7,9,11月
20. 特定日期范围 + 时间(如国庆期间每天9点)
0 0 9 1-7 10 ?
10月1日至7日,每天9:00 执行
Cron格式校验工具推荐
https://www.freeformatter.com/cron-expression-generator-quartz.html
更多推荐


所有评论(0)