2014-09-24 38 views
8

我可以使用Quartz Scheduler庫,設置如下?:我可以使用Quartz Scheduler在第30天每隔一個月發射一次,但如果月份沒有第30天,最後一天發射?

  • 月,30日開始創建計劃2014
  • 執行每30天
  • 每2個月因此
  • 如果月份沒有第30天,則應在的最後一天發生操作。

因此,所產生的時間表將是:

  • 2014年12月30日
  • 月,2015年
  • 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(); 
    } 
    

如果沒有,是否有任何替代品(它應該在JBoss EAP 6.2.0工作)?

+3

最遲的實施:每天開啓工作,檢查工作開始時是否有效。我不知道你的情況會有多麼實際(安裝成本等),但它可以讓你使用日期API,將正確的日期邏輯移動到一個方法,記錄和測試它,等等。 – ssube 2014-09-24 14:03:40

回答

5

你可以在Quartz中實現這個功能,但是你必須通過使用CalendarIntervalTrigger來觸發一個Job來計算你的'真實'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); 

而在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); 
    } 
} 

這是一個有點蘇族,但我已經使用它,我工作正常。

+0

好一個! Upvoting,現在我有東西堅持:)。 我想也許有更多的「計劃」的方式來做到這一點,而無需額外的計算或一些Quartz方法將具體日期添加到CalendarIntervalTrigger ...我會等待一段時間,如果沒有,我會接受你的答案。 – n1k1ch 2014-09-24 14:21:53

+1

我稍微增強了一些代碼,您只需要在'execute'方法中檢索'真正'的工作細節和調度程序引用,其餘部分應該可以工作;) – Kraiss 2014-09-24 14:30:02

+0

我們可以在某處指定結束日期嗎?直到它會觸發? – Elizabeth 2016-04-07 06:56:29

相關問題