将Quartz表达式用于下一个工作日

时间:2014-08-04 09:00:22

标签: java scheduled-tasks quartz-scheduler

我需要创建一个Quartz cron表达式,如果它是工作日,则每月的第10天触发,否则将触发 next 日或之后的第二天下。

  • E.g。 2014年8月10日星期日,星期一11日开火
  • E.g。 2014年9月10日是Wednesiday,星期三10日开火。
  • E.g。 2015年1月10日是星期六,星期一12日开火

我强调了第三种情况:我尝试0 0 0 10W * ?作为表达,但它在2015年1月8日星期五发布。我需要稍后解雇。

我如何告诉Quartz?我想制作三个表达式,例如"如果是工作日,则为第10个",如果是星期一,则为#11; 11;"和#12;如果它是星期一"但是我不能将日期和星期几字段组合在一起(我总是得到一个无效的cron表达式错误)

1 个答案:

答案 0 :(得分:0)

我认为你不能用简单的cron表达式做到这一点,但你可以使用以下解决方案。

首先使用经典的Cron触发器安排您的工作

    CronScheduleBuilder sh = cronSchedule("0 0 0 10 * ?");
    TriggerBuilder<Trigger> tb = newTrigger()
        .withSchedule(sh)
        .withIdentity("MyTrigger");

安排你的触发器。然后创建一个实现mecanism的Quartz TriggerListener

    public class MyTriggerListener implements TriggerListener {
         [...]

         @Override
         public void vetoJobExecution(Trigger trigger, JobExecutionContext context) {

              // You check if it is your Cron Trigger
              if ("MyTrigger".equals(trigger.getKey.getName()) {
                   Calendar cal = Calendar.getInstance();

                   // If current date is sunday, then another one-time trigger 
                   //   is created to delay the job firing
                   if (Calendar.SUNDAY.equals(cal.get(Calendar.DAY_OF_WEEK))) {

                        cal.add(Calendar.DATE, 1); // One day later

                        TriggerBuilder<Trigger> tb = newTrigger()
                            .startAt(cal.getTime());
                            .withIdentity("MyTrigger_delayed");
                            .forJob(context.getJobDetail());

                        // TODO schedule it in Quartz the way you want
                        // like : scheduler.scheduleJob(tb.build());

                        return true; // The current fire is vetoed
                   }

                   // If current date is saturday, then another one-time trigger 
                   //   is created to delay the job firing
                   else if (Calendar.SATURDAY.equals(cal.get(Calendar.DAY_OF_WEEK))) {

                        cal.add(Calendar.DATE, 2); // Two day later

                        TriggerBuilder<Trigger> tb = newTrigger()
                            .startAt(cal.getTime());
                            .withIdentity("MyTrigger_delayed");
                            .forJob(context.getJobDetail());

                        // TODO schedule it in Quartz the way you want
                        // like : scheduler.scheduleJob(tb.build());

                        return true;// The current fire is vetoed
                   } 
                   // If it is a weekday, the job fires normally
                   else {
                        return false;
                   }
              }

              // It is not your Cron Trigger
              return false;
         }
    }

这段代码实现了一种机制,可以延迟你的工作开始工作工作日。您可以使用

将此监听器添加到计划程序
        TriggerListener myTriggerListener = new MyTriggerListener("MyTriggerListener");
        scheduler.getListenerManager().addTriggerListener(myTriggerListener, allTriggers());