2011-12-19 36 views
5

Tôi đang cố viết một biểu thức cron đơn giản cho trình lên lịch thạch anh. Tôi muốn công việc chạy hàng tháng vào ngày 30 lúc 3 giờ sáng.Quartz cron - nếu ngày trong tháng không tồn tại thì sao?

0 0 3 30 JAN-DEC ? * 

Tôi tự hỏi điều gì sẽ xảy ra trong tháng 2? Công việc sẽ chạy hay không chạy?

Tôi không tìm kiếm giải pháp cuối cùng của tháng, tôi cần người dùng chọn ngày trong tháng khi công việc sẽ chạy (lý tưởng một lần cho tất cả các tháng).

Trả lời

4

L ("cuối cùng") - có ý nghĩa khác nhau trong từng trường trong số hai trường được phép. Ví dụ: giá trị "L" trong trường ngày của tháng có nghĩa là "ngày cuối cùng của tháng" - ngày 31 cho tháng 1, ngày 28 cho tháng 2 vào những năm không phải là năm nhuận. Nếu được sử dụng trong trường ngày-tuần, nó chỉ đơn giản có nghĩa là "7" hoặc "SAT". Nhưng nếu được sử dụng trong trường ngày trong tuần sau một giá trị khác, nó có nghĩa là "ngày xxx cuối cùng của tháng" - ví dụ "6L" có nghĩa là "Thứ Sáu cuối cùng của tháng". Khi sử dụng tùy chọn 'L', điều quan trọng là không chỉ định danh sách hoặc phạm vi giá trị vì bạn sẽ nhận được kết quả khó hiểu.

Bạn có thể sử dụng điều này để chỉ định thay vì chỉ định 30 trong công việc ngô của bạn trực tiếp.

http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger

Kiểm tra ký tự đặc biệt.

Cảm ơn.

+1

Vâng, tôi không quan tâm để chạy các công việc trên trước, hoặc thứ hai ngày cuối cùng của tháng. Tôi chỉ cần nó trên 30 (nếu ngày đó tồn tại). – dcernahoschi

1

Nó sẽ không chạy. Nếu bạn muốn nó chạy trong 28 trong trường hợp của tháng hai, bạn phải tạo nhiều CronExpressions cho mỗi trường hợp của ngày trong tháng, và một kích hoạt cho mỗi một, và sau đó thêm tất cả các kích hoạt cho công việc yêu cầu của bạn.

Đây là những gì tôi đã làm:

CronExpressions tạo:

public static List<CronExpression> getCronExpressionList(int seconds, int minutes, 
      int hours, int dayInMonth, Month month, 
      DayOfWeek dayOfWeek) { 
    final String monthsWith30Days = Month.APR + "," + Month.JUN + "," 
        + Month.SEP + "," + Month.NOV; 
    List<CronExpression> crons = new LinkedList<CronExpression>(); 

    String timeString = String.format(("%s %s %s "), seconds, minutes, 
        hours, 0, 0, 0); 
    String dateString = "%s %s %s"; 
    String cron = null; 

    cron = timeString + String.format(dateString, dayInMonth, "*", "?"); 
    crons.add(new CronExpression(cron)); 
    if (dayInMonth > 28) { 
     String febCron = timeString + getFebruarLastDayDateString(dateString); 
     crons.add(new CronExpression(febCron)); 
     if (dayInMonth == 31) { 
      String monthsWithThirtyDaysCron = timeString + String.format(dateString, 
        "L", monthsWith30Days, "?"); 
      crons.add(new CronExpression(monthsWithThirtyDaysCron)); 
     } 
    } 
    return crons; 
} 

private static String getFebruarLastDayDateString(String initialCron) 
       throws ParseException { 
    return String.format(initialCron, "L", Month.FEB, "?"); 
} 

tạo Trigger:

 Set<CronTrigger> triggers = new HashSet<>(); 

     int i = 1; 
     for (CronExpression cronEx : cronsList) { 
      CronTrigger trigger = newTrigger() 
        .withIdentity("trigger" + i, groupName) 
        .withSchedule(cronSchedule(cronEx)) 
        .build(); 
       triggers.add(trigger); 
       i++; 
     } 
0

kiểm tra mã đơn giản

public class TestCronTrigger { 

    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); 

    public static void main(String[] args) throws Exception { 

     String dateStr = "2015-02-10"; 
     String cron = "0 0 0 31 * ?"; 
     Date nextFireTime = getNextFireTimeFromDateForCron(DATE_FORMAT.parse(dateStr), cron); 
     System.out.println(String.format("For cron '%s' next fire time after '%s' will be '%s'", cron, dateStr, DATE_FORMAT.format(nextFireTime))); 

     dateStr = "2015-02-10"; 
     cron = "0 0 0 30 * ?"; 
     nextFireTime = getNextFireTimeFromDateForCron(DATE_FORMAT.parse(dateStr), cron); 
     System.out.println(String.format("For cron '%s' next fire time after '%s' will be '%s'", cron, dateStr, DATE_FORMAT.format(nextFireTime))); 

     dateStr = "2015-02-10"; 
     cron = "0 0 0 28 * ?"; 
     nextFireTime = getNextFireTimeFromDateForCron(DATE_FORMAT.parse(dateStr), cron); 
     System.out.println(String.format("For cron '%s' next fire time after '%s' will be '%s'", cron, dateStr, DATE_FORMAT.format(nextFireTime))); 

     dateStr = "2015-03-10"; 
     cron = "0 0 0 31 * ?"; 
     nextFireTime = getNextFireTimeFromDateForCron(DATE_FORMAT.parse(dateStr), cron); 
     System.out.println(String.format("For cron '%s' next fire time after '%s' will be '%s'", cron, dateStr, DATE_FORMAT.format(nextFireTime))); 

    } 

    static Date getNextFireTimeFromDateForCron(Date from, String cron) throws ParseException { 
     CronTriggerImpl cronTrigger = new CronTriggerImpl(); 
     cronTrigger.setCronExpression(cron); 
     cronTrigger.setStartTime(from); 
     return cronTrigger.computeFirstFireTime(null); 
    } 
} 

Đối với mã này outp ut sẽ là:

For cron '0 0 0 31 * ?' next fire time after '2015-02-10' will be '2015-03-31' 
For cron '0 0 0 30 * ?' next fire time after '2015-02-10' will be '2015-03-30' 
For cron '0 0 0 28 * ?' next fire time after '2015-02-10' will be '2015-02-28' 
For cron '0 0 0 31 * ?' next fire time after '2015-03-10' will be '2015-03-31' 

chơi với đối số bạn có thể tìm thấy câu trả lời

+0

Đây chỉ là câu trả lời gián tiếp. Tôi sẽ là tuyệt vời nếu bạn có thể thêm những gì đầu ra bạn nhận được cho các giá trị được đưa ra bởi OP. Điều này sẽ làm cho câu trả lời của bạn hoàn chỉnh hơn. – honk

Các vấn đề liên quan