【发布时间】:2012-01-23 13:08:05
【问题描述】:
我正在尝试为石英调度程序编写一个简单的 cron 表达式。我希望该作业在每个月的第 30 天凌晨 3 点运行。
0 0 3 30 JAN-DEC ? *
我想知道二月份会发生什么?作业会运行还是不运行?
我不是在寻找每月最后一天的解决方案,我需要用户选择作业将在每月的哪一天运行(最好是所有月份一次)。
【问题讨论】:
标签: java cron quartz-scheduler
我正在尝试为石英调度程序编写一个简单的 cron 表达式。我希望该作业在每个月的第 30 天凌晨 3 点运行。
0 0 3 30 JAN-DEC ? *
我想知道二月份会发生什么?作业会运行还是不运行?
我不是在寻找每月最后一天的解决方案,我需要用户选择作业将在每月的哪一天运行(最好是所有月份一次)。
【问题讨论】:
标签: java cron quartz-scheduler
L(“最后一个”) - 在允许使用的两个字段中的每个字段中都有不同的含义。例如,day-of-month 字段中的值“L”表示“月的最后一天”——非闰年 1 月的第 31 天,2 月的第 28 天。如果单独在星期几字段中使用,它仅表示“7”或“SAT”。但是如果在星期几字段中使用另一个值,则表示“本月的最后 xxx 天”——例如“6L”表示“本月的最后一个星期五”。使用“L”选项时,重要的是不要指定列表或值范围,因为您会得到令人困惑的结果。
您可以使用它来指定而不是直接在您的玉米作业中指定 30。
http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger
检查特殊字符。
谢谢。
【讨论】:
它不会运行。如果您希望它在 2 月的情况下在 28 日运行,则必须为每个月的天数创建多个 CronExpressions,并为每个天数创建一个触发器,然后将所有触发器添加到所需的作业中。
这就是我所做的:
CronExpressions 创建:
public static List<CronExpression> getCronExpressionList(int seconds, int minutes,
int hours, int dayInMonth, Month month,
DayOfWeek dayOfWeek) {
final String monthsWith30Days = Month.APR + "," + Month.JUN + ","
+ Month.SEP + "," + Month.NOV;
List<CronExpression> crons = new LinkedList<CronExpression>();
String timeString = String.format(("%s %s %s "), seconds, minutes,
hours, 0, 0, 0);
String dateString = "%s %s %s";
String cron = null;
cron = timeString + String.format(dateString, dayInMonth, "*", "?");
crons.add(new CronExpression(cron));
if (dayInMonth > 28) {
String febCron = timeString + getFebruarLastDayDateString(dateString);
crons.add(new CronExpression(febCron));
if (dayInMonth == 31) {
String monthsWithThirtyDaysCron = timeString + String.format(dateString,
"L", monthsWith30Days, "?");
crons.add(new CronExpression(monthsWithThirtyDaysCron));
}
}
return crons;
}
private static String getFebruarLastDayDateString(String initialCron)
throws ParseException {
return String.format(initialCron, "L", Month.FEB, "?");
}
触发器创建:
Set<CronTrigger> triggers = new HashSet<>();
int i = 1;
for (CronExpression cronEx : cronsList) {
CronTrigger trigger = newTrigger()
.withIdentity("trigger" + i, groupName)
.withSchedule(cronSchedule(cronEx))
.build();
triggers.add(trigger);
i++;
}
【讨论】:
检查简单代码
public class TestCronTrigger {
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
public static void main(String[] args) throws Exception {
String dateStr = "2015-02-10";
String cron = "0 0 0 31 * ?";
Date nextFireTime = getNextFireTimeFromDateForCron(DATE_FORMAT.parse(dateStr), cron);
System.out.println(String.format("For cron '%s' next fire time after '%s' will be '%s'", cron, dateStr, DATE_FORMAT.format(nextFireTime)));
dateStr = "2015-02-10";
cron = "0 0 0 30 * ?";
nextFireTime = getNextFireTimeFromDateForCron(DATE_FORMAT.parse(dateStr), cron);
System.out.println(String.format("For cron '%s' next fire time after '%s' will be '%s'", cron, dateStr, DATE_FORMAT.format(nextFireTime)));
dateStr = "2015-02-10";
cron = "0 0 0 28 * ?";
nextFireTime = getNextFireTimeFromDateForCron(DATE_FORMAT.parse(dateStr), cron);
System.out.println(String.format("For cron '%s' next fire time after '%s' will be '%s'", cron, dateStr, DATE_FORMAT.format(nextFireTime)));
dateStr = "2015-03-10";
cron = "0 0 0 31 * ?";
nextFireTime = getNextFireTimeFromDateForCron(DATE_FORMAT.parse(dateStr), cron);
System.out.println(String.format("For cron '%s' next fire time after '%s' will be '%s'", cron, dateStr, DATE_FORMAT.format(nextFireTime)));
}
static Date getNextFireTimeFromDateForCron(Date from, String cron) throws ParseException {
CronTriggerImpl cronTrigger = new CronTriggerImpl();
cronTrigger.setCronExpression(cron);
cronTrigger.setStartTime(from);
return cronTrigger.computeFirstFireTime(null);
}
}
对于此代码,输出将是:
For cron '0 0 0 31 * ?' next fire time after '2015-02-10' will be '2015-03-31'
For cron '0 0 0 30 * ?' next fire time after '2015-02-10' will be '2015-03-30'
For cron '0 0 0 28 * ?' next fire time after '2015-02-10' will be '2015-02-28'
For cron '0 0 0 31 * ?' next fire time after '2015-03-10' will be '2015-03-31'
玩弄你能找到答案的论据
【讨论】:
下面的代码计算每个月最后一天的下一个触发日期
static Date getNextFireTimeFromDateForCron() throws ParseException {
CronTriggerImpl cronTrigger = new CronTriggerImpl();
cronTrigger.setCronExpression("0 15 15 L * ?");
cronTrigger.setStartTime(new Date());
return cronTrigger.computeFirstFireTime(null);
}
【讨论】: