我可以在第30天使用Quartz Scheduler每隔一个月开一次,但如果月没有第30天,那么最后一天会开火吗?

n1k*_*1ch 11 java quartz-scheduler jboss-eap-6

我可以使用Quartz Scheduler库创建具有以下设置的计划吗?:

  • 2014年12月30日开始
  • 每30天执行一次
  • 每2个月结果
  • 如果月份没有第30天,则应在每月最后一天采取措施.

因此,产生的时间表将是:

  • 2014年12月30日
  • 2015年2月28
  • 2015年4月30日
  • ... 等等

从我所学到的:

  1. CronTrigger不允许这样做(它可以设置为仅在特定月份触发,而不是间隔触发),
  2. CalendarIntervalTrigger将跳过没有第30天的月份(由以下代码创建的触发器)

    try {
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        Scheduler scheduler = schedulerFactory.getScheduler();
        scheduler.start();
    
        JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
                .withIdentity("HelloJob_CalendarIntervaled", "calendarIntervaled")
                .build();
    
        Calendar decemberThirty = Calendar.getInstance();
        decemberThirty.set(Calendar.YEAR, 2014);
        decemberThirty.set(Calendar.MONTH, Calendar.DECEMBER);
        decemberThirty.set(Calendar.DAY_OF_MONTH, 30);
    
        CalendarIntervalTrigger calendarIntervalTrigger = newTrigger()
                .withIdentity("calendarIntervalTrigger", "calendarIntervaled")
                .withSchedule(CalendarIntervalScheduleBuilder.calendarIntervalSchedule()
                        .withIntervalInMonths(2))
                .startAt(decemberThirty.getTime())
                .forJob(jobDetail)
                .build();
    
        scheduler.scheduleJob(jobDetail, calendarIntervalTrigger);
    
        System.out.println(calendarIntervalTrigger.getNextFireTime());
    } catch (SchedulerException e) {
        e.printStackTrace();
    }
    
    Run Code Online (Sandbox Code Playgroud)

如果没有,有没有其他选择(它应该适用于JBoss eap 6.2.0)?

Kra*_*iss 7

您可以在Quartz中实现这一点,但是您必须通过使用a CalendarIntervalTrigger来触发计算何时应该安排"真实"作业的Job 来扭曲正常行为.

您安排了触发器,该触发器每隔一个计划月份触发一次:

[...]
JobDetail jobDetail = newJob(SchedulingCalculationJob.class)
        .withIdentity("SchedulingCalculation_CalendarIntervaled", "calendarIntervaled")
        .build();

CalendarIntervalTrigger calendarIntervalTrigger = newTrigger()
        .withIdentity("calendarIntervalCalculationTrigger", "calendarIntervaled")
        .withSchedule(calendarIntervalSchedule()
                .withIntervalInMonths(2))
        .startAt(decemberFirst.getTime())
        .forJob(jobDetail)
        .build();

scheduler.scheduleJob(jobDetail, calendarIntervalTrigger);
Run Code Online (Sandbox Code Playgroud)

SchedulingCalculationJob工作中,您计算​​"真正的"工作安排日:

public class SchedulingCalculationJob implements Job {

    public void execute(JobExecutionContext context)
            throws JobExecutionException {

        Calendar calendar = calculateJobFiringDate();

        // Create and schedule a dedicated trigger
        Trigger calculateFiring = calculateFiring = newTrigger()
               .withSchedule(SimpleSchedulerBuilder.simpleScheduler())
               .startAt(calendar.getTime())
               .forJob(yourRealJobDetail)
               .build();

        scheduler.scheduleJob(yourRealJobDetail, calculateFiring);
    }

    public static Calendar calculateJobFiringDate() {
        Calendar result = Calendar.getInstance();

        // Set up the scheduling day
        if (isThereThirtyDaysInCurrentMonth()) {
            // the 30th of the current month
            calendar.set(Calendar.DAY_OF_MONTH, 30);
        } else {
            // the last day of the current month
            calendar.add(Calendar.MONTH, 1);
            calendar.add(Calendar.DATE, -1);
        }

        // Set up time of day
        calendar.set(Calendar.HOUR, ...);
        calendar.set(Calendar.MINUTE, ...);
        calendar.set(Calendar.SECOND, ...);

        return result;
    }

    public static boolean isThereThirtyDaysInCurrentMonth() {
        Calendar thirtydaysInCurrentMonthCalendar = Calendar.getInstance();

        Integer currentMonth = thirtydaysInCurrentMonthCalendar.get(Calendar.MONTH);
        thirtydaysInCurrentMonthCalendar.add(Calendar.DATE, 29);

        return (currentMonth == thirtydaysInCurrentMonthCalendar.get(Calendar.MONTH);
    }
}
Run Code Online (Sandbox Code Playgroud)

这有点苏,但我已经使用它,我工作正常.