Posticipate Quartz expression to the next weekday

北城以北 提交于 2021-01-28 04:52:00

问题


I need to create a Quartz cron expression that fires every 10th day of the month if it is a weekday, otherwise fires to the next day or the day after the next.

  • E.g. August 10th 2014 is Sunday, fire Monday 11th
  • E.g. September 10th 2014 is Wednesiday, fire Wednesday 10th
  • E.g. January 10th 2015 is Saturday, fire Monday 12th

I highlighted the third case: I tried 0 0 0 10W * ? as expression but it fires Friday Jan 8th 2015. I need it to be fired later.

How do I tell Quartz to? I wanted to make three expressions, e.g. "the 10th if it is a weekday", "11th if it is a monday" and "12th if it is a monday" but I can't combine day-of-month and day-of-week fields (I always get an Invalid cron expression error)


回答1:


I don't think you can do that with a simple cron expression, but you can use the following solution.

First schedule your Job with a classic Cron Trigger

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

And schedule your Trigger. Then create a Quartz TriggerListener that implements your mecanism

    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;
         }
    }

This code implement a mecanism to delayed your job firing to start the job a weekday. You can add this Listener to your Scheduler with

        TriggerListener myTriggerListener = new MyTriggerListener("MyTriggerListener");
        scheduler.getListenerManager().addTriggerListener(myTriggerListener, allTriggers());


来源:https://stackoverflow.com/questions/25115034/posticipate-quartz-expression-to-the-next-weekday

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!