1

I'd like to trigger a job every 2 weeks on Monday and Tuesday at 10:00am (as an example) in Quartz 2.2.1.

I'd though about using a CronTrigger but unfortunately a cron job can't be set up for "every 2 weeks" (see explanation here). Using a CalendarIntervalTrigger also seems not to fit as I couldn't find a support for weekdays.

Is there a solution doing this Quartz?

John
  • 896
  • 7
  • 25
  • 2
    Not really an answer but you could do "0 0 10 ? * MON,TUE *" and in your cron do a alternating run=!run; if(run) doChron. so every other week would run. Also you can play with http://www.cronmaker.com/ is super helpful – ug_ Oct 14 '13 at 17:54
  • @John i have the same question, have you found the solution for that john? i have been working on that for few days now without fruitful result. if you do, can you share your way of implement it? – Ridzuan Adris Jun 06 '14 at 02:23
  • 1
    Well, I've ended up subclassing org.quartz.impl.triggers.AbstractTrigger. For the "Monday and Tuesday at 10:00am" part you can use a CronTrigger internally (e.g. using CronScheduleBuilder). Unfortunately, the "every 2 weeks" part you have to implement yourself. If it helps, I can post fragments of the code as an answer here (I'm not allowed to disclose the full code). – John Jun 06 '14 at 09:28
  • Thank you for your reply @john, It nice to know we still need to apply crontrigger. I am currently try to work out for that every 2 week part as each quartz function(crontrigger simple trigger and calendarIntervalTrigger) have limitation to apply our requirement. for intervalCalendartrigger, eventhough it have method for week interval, it seem there are no solution to run on weekday like cron. simpleinteger does not have weekly interval and it intervalinhour for weekday does not support bigger than 24 hours interval. – Ridzuan Adris Jun 09 '14 at 01:28
  • sure @john, a fragment of code would be really helpful, i need to understand the logic on how to implement it and then i can come out with the code part. You can post it as answer and later i can share mine to the community. – Ridzuan Adris Jun 09 '14 at 01:32

3 Answers3

1

The key idea is using a cron trigger for the "Monday and Tuesday at 10:00am". As that cron trigger will fire every week, you have to implement the "every two weeks" parts by yourself. So for calculating the next fire time after a certain date you let the cron trigger give you its next fire time and check whether you're in the correct week. If not you add an offset to get in the correct week.

This all can be done by overriding AbstractTrigger. As an example I'll show one of the key methods, getFireTimeAfter:

public class MyTrigger extends AbstractTrigger<MyTrigger> {

    //your cron trigger for Monday and Tuesday at 10:00am
    private OperableTrigger trigger;        

    //initialize this with the first fire time in method computeFirstFireTime
    private Date firstFireTime;     

    //fire every N weeks
    private int nboWeeks;

//...

    @Override
    public Date getFireTimeAfter(Date afterTime) {

        //Get the fire time of the cron trigger after afterTime
        Date cronFireTime = trigger.getFireTimeAfter(afterTime);

        //we have to determine whether we're in the correct week        
        int weeksSinceFirstFire = ...; //calculate the nbo weeks since firing for the first time
        int weekOffset = weeksSinceFirstFire % nboWeeks;

        //we won't fire any more or are in the correct week
        if (cronFireTime == null || weekOffset == 0) {
            return cronFireTime;
        }

        int weeksToAdd = weeksSinceFirstFire - weekOffset;
        Date fireTime = ...; // add weeksToAdd to cronFireTime

        return fireTime;
    }
//...
}
John
  • 896
  • 7
  • 25
0

Job execution every n weeks on weekdays a and b at x o'clock in Quartz

to run job on monday and tuesday at 10am, we need to identify the latest date of monday and tuesday first. and then use those date as startdate at CalendarIntervalTrigger.

identify the date of latest/next monday and tuesday from today date. the code can be found here.then applied the date on Quartz calendarIntervalSchedule.

 //dd.M.yyyy hh:mm:ss a
 //Monday
 String getMondayDate = "23 JUNE 2014 10:0:0 am"
 String MONDAY = getMondayDate;

 Date startDate = new SimpleDateFormat("dd.M.yyyy hh:mm:ss a").parse(MONDAY);

 Trigger trigger = newTrigger()
    .withIdentity("mondayTrigger", "group1")
    .startAt(startDate)  //put retrieved monday date here
    .withSchedule(calendarIntervalSchedule()
            .withIntervalInWeeks(2)) // interval is set in calendar weeks
    .build();

//Tuesday
String getTuedayDate = "24 JUNE 2014 10:0:0 am"
String TUESDAY = getTuesdayDate;

Date startDate = new SimpleDateFormat("dd.M.yyyy hh:mm:ss a").parse(TUESDAY);

Trigger trigger = newTrigger()
    .withIdentity("mondayTrigger", "group1")
    .startAt(startDate)  //put retrieved monday date here
    .withSchedule(calendarIntervalSchedule()
        .withIntervalInWeeks(2)) // interval is set in calendar weeks
    .build();
Community
  • 1
  • 1
Ridzuan Adris
  • 1,192
  • 2
  • 13
  • 32
0

This should implement the clone interface. otherwise the trigger will get the wrong fire time.

JinruiDu
  • 353
  • 1
  • 2
  • 9