2009-08-05 7 views
12

Tôi đang sử dụng Quartz với Java để lên lịch công việc. Một điều là tôi lưu trữ các biểu thức cron trên cơ sở dữ liệu và tôi muốn trình bày chúng cho người dùng nhưng ở dạng dễ đọc hơn. Vì vậy, tôi đã tự hỏi nếu có một tiện ích có thể chuyển đổi một biểu thức cron thành một chuỗi có thể đọc được của con người. Một cái gì đó như:Cron đến chuỗi có thể đọc được của con người

"" 0 30 10-13? * WED, FRI " sẽ trở thành " Bắn vào lúc 10:30, 11:30, 12:30 và 13:30, vào mọi Thứ Tư và Thứ Sáu. "

+4

Bạn đã bao giờ thực hiện một giải pháp tốt đẹp? Tôi cần phải làm chính xác như vậy, bạn có bất kỳ gợi ý/chiến lược nào giúp giảm bớt việc triển khai của tôi không? –

+0

Tôi không sợ ... Điều này là cần thiết cho sản xuất và công ty của tôi không coi đó là ưu tiên hàng đầu. Thay vào đó, chúng tôi đã chọn chỉ hiển thị thời gian lửa tiếp theo cho các công việc cron: S Nhưng câu trả lời tôi chấp nhận bên dưới cung cấp điểm bắt đầu để làm việc với cron. Tôi không biết làm thế nào dễ dàng được mặc dù ... –

Trả lời

19

thư viện Một Java có thể chuyển đổi biểu thức cron thành chuỗi có thể đọc được con người: https://github.com/RedHogs/cron-parser

+12

Tôi thích nó rằng Stackoverflow cung cấp câu trả lời đúng cho một câu hỏi thậm chí 5 năm sau khi được hỏi. :) Chúc mừng –

0

CronTrigger tạo đối tượng CronExpression từ biểu thức cron . chuỗi Nhưng bạn không thể truy cập vào nó Nhưng bằng cách sử dụng phản ánh bạn có thể:.

Class c = cronTrigger.getClass(); 
Field f = c.getDeclaredField("cronEx"); 
f.setAccessible(true); 
CronExpression cronEx = (CronExpression) f.get(cronTrigger); 
+1

tôi nghĩ rằng bạn không hiểu câu hỏi của tôi –

9

Vâng vâng tôi đã hiểu câu hỏi của bạn Nhưng tôi nên đã giải thích câu trả lời của tôi tốt hơn một chút

không tôi.. không biết bất kỳ công cụ nào sẽ giúp bạn có được một biểu thức cron trong dạng có thể đọc được "con người". truy cập vào CronExpression bạn có thể tạo riêng cho mình.

thử gọi

cronTrigger.getExpressionSummary() 

trên biểu thức cron:

"0/2 * * 4 * ?" 

nó trả về chuỗi sau:

seconds: 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58 
minutes: * 
hours: * 
daysOfMonth: 4 
months: * 
daysOfWeek: ? 
lastdayOfWeek: false 
nearestWeekday: false 
NthDayOfWeek: 0 
lastdayOfMonth: false 
calendardayOfWeek: false 
calendardayOfMonth: false 
years: * 

Bởi có quyền truy cập vào các đối tượng CronExpression, bạn có thể tạo riêng của "con người" explenation.

+0

có cảm ơn cho câu trả lời. có vẻ như tôi sẽ tạo phiên bản của mình. –

2

đây là lần đầu tôi bắt đầu. nó sử dụng ngôn ngữ mà người dùng của tôi sẽ (có thể) hiểu.

nó sẽ không hoạt động tốt với các hỗn hợp mã thông báo như '1,13,16-23, L' cho mã thông báo ngày, nhưng hy vọng, tôi sẽ dành chút thời gian để sử dụng nó trước khi người dùng của tôi trở thành tinh vi:

 
package com.tacteonltd.control.cron; 

import java.util.StringTokenizer; 

import com.tacteonltd.control.string.STRING; 
import com.tacteonltd.control.time.TIME; 

public class CRON { 
    public static String humanReadable(String value){ 
     StringBuffer sb = new StringBuffer(); 
     try{ 
      StringTokenizer tokens = new StringTokenizer(value, " ", false); 
      humanizeSeconds(tokens.nextToken(), sb);sb.append("\n"); 
      humanizeMinutes(tokens.nextToken(), sb);sb.append("\n"); 
      humanizeHours(tokens.nextToken(), sb);sb.append("\n"); 
      String dom = tokens.nextToken(); 
      String month = tokens.nextToken(); 
      String dow = tokens.nextToken(); 
      humanizeDOMs(dom, dow, sb);sb.append("\n"); 
      humanizeMonths(month, sb);sb.append("\n"); 
      humanizeDOWs(dow, dom, sb); 
     }catch(Throwable t){ 
      t.printStackTrace(); 
     } 
     return sb.toString(); 
    } 
    private static void humanizeDOWs(String value, String dom, StringBuffer sb){ 
     value=value.trim(); 
     if(STRING.isNumeric(value)){ 
      sb.append("and the " + value + postFix(value) + " day-of-the-week("+TIME.getWeekDayName(Integer.parseInt(value))+"). "); 
     } 
     else if(value.equals("*")) 
     { 
      sb.append("and every day-of-the-week. "); 
     } 
     else if(value.equals("?")) 
     { 
      sb.append("and whatever day-of-the-week it is for day"+(STRING.isNumeric(dom) ? "":"s")+"-of-the-month :"+(STRING.isNumeric(dom) ? dom:"that match"+(STRING.isNumeric(dom) ? "es":"")+" " + dom + ".")); 
     } 
     else if(value.indexOf("/")>-1){ 
      String first = value.substring(0, value.indexOf("/")); 
      String every = value.substring(value.indexOf("/") + 1); 
      sb.append("and the " + first + postFix(first) + " day-of-the-week and every " + every + " day" + (Integer.parseInt(every) == 1 ? "":"s") + " following. "); 
     } 
     else if(value.indexOf(",")>-1){ 
      StringTokenizer tokens = new StringTokenizer(value, ",", false); 
      sb.append("and the following days of the week: "); 
      int added = 0; 
      while(tokens.hasMoreTokens()){ 
       String token = tokens.nextToken(); 
       sb.append((added==0 ? "":", ") + token);added++; 
      } 
      sb.append("."); 
     } 
     else if(value.indexOf("-")>-1){ 
      StringTokenizer tokens = new StringTokenizer(value, "-", false); 
      sb.append("and for every day of the week from " + tokens.nextToken() + " through " + tokens.nextToken() + ". "); 
     } 
     else { 
      sb.append("and the following days of the week: " + value + "."); 
     } 
    } 
    private static void humanizeMonths(String value, StringBuffer sb){ 
     value=value.trim(); 
     if(STRING.isNumeric(value)){ 
      sb.append("the " + value + postFix(value) + " month("+TIME.getMonthName(Integer.parseInt(value))+"), "); 
     } 
     else if(value.equals("*")) 
     { 
      sb.append("every month, "); 
     } 
     else if(value.indexOf("/")>-1){ 
      String first = value.substring(0, value.indexOf("/")); 
      String every = value.substring(value.indexOf("/") + 1); 
      sb.append("the " + first + postFix(first) + " month("+TIME.getMonthName(Integer.parseInt(value))+") and every " + every + " month" + (Integer.parseInt(every) == 1 ? "":"s") + " following, "); 
     } 
     else if(value.indexOf(",")>-1){ 
      StringTokenizer tokens = new StringTokenizer(value, ",", false); 
      sb.append("the following months: "); 
      int added = 0; 
      while(tokens.hasMoreTokens()){ 
       sb.append((added==0 ? "":", ") + tokens.nextToken());added++; 
      } 
     } 
    } 
    private static void humanizeDOMs(String value, String dow, StringBuffer sb){ 
     value=value.trim(); 
     if(STRING.isNumeric(value)){ 
      sb.append("the " + value + postFix(value) + " day-of-the-month, "); 
     } 
     else if(value.equals("*")) 
     { 
      sb.append("every day-of-the-month, "); 
     } 
     else if(value.equals("?")) 
     { 
      sb.append("whatever day-of-the-month falls upon " + dow + " , "); 
     } 
     else if(value.indexOf("-")>-1){ 
      StringTokenizer tokens = new StringTokenizer(value, "-", false); 
      String from = tokens.nextToken(); 
      String through = tokens.nextToken(); 
      int year = TIME.getYear(System.currentTimeMillis()); 
      int month = TIME.getMonth(System.currentTimeMillis()); 
      String last_dom = "" + TIME.getLastDOM(year, month); 
      sb.append("for every day of the month from " + from + " through " + (through.equals("L") ? "the last("+year +"." +month + "."+last_dom+")":through)); 
     } 
     else if(value.indexOf("/")>-1){ 
      String first = value.substring(0, value.indexOf("/")); 
      String every = value.substring(value.indexOf("/") + 1); 
      sb.append("the " + first + postFix(first) + " day-of-the-month and every " + every + " day" + (Integer.parseInt(every) == 1 ? "":"s") + " following, "); 
     } 
     else if(value.indexOf(",")>-1){ 
      StringTokenizer tokens = new StringTokenizer(value, ",", false); 
      sb.append("the following days of the month: "); 
      int added = 0; 
      while(tokens.hasMoreTokens()){ 
       String token = tokens.nextToken(); 
       if(token.equals("L")){ 
        int year = TIME.getYear(System.currentTimeMillis()); 
        int month = TIME.getMonth(System.currentTimeMillis()); 
        String last_dom = "" + TIME.getLastDOM(year, month); 
        sb.append((added==0 ? "":", ") + "the last("+year +"." +month + "."+last_dom+")"); 
       } 
       else{ 
        sb.append((added==0 ? "":", ") + token);added++; 
       } 
      } 
     } 
    } 
    private static void humanizeSeconds(String value, StringBuffer sb){ 
     value=value.trim(); 
     if(STRING.isNumeric(value)){ 
      sb.append("on the " + value + postFix(value) + " second, "); 
     } 
     else if(value.equals("*")) 
     { 
      sb.append("on every second, "); 
     } 
     else if(value.indexOf("/")>-1){ 
      String first = value.substring(0, value.indexOf("/")); 
      String every = value.substring(value.indexOf("/") + 1); 
      sb.append("on the " + first + postFix(first) + " second and every " + every + " second" + (Integer.parseInt(every) == 1 ? "":"s") + " following, "); 
     } 
     else if(value.indexOf("-")>-1){ 
      StringTokenizer tokens = new StringTokenizer(value, "-", false); 
      sb.append("for every second from " + tokens.nextToken() + " through " + tokens.nextToken() + " "); 
     } 
     else if(value.indexOf(",")>-1){ 
      StringTokenizer tokens = new StringTokenizer(value, ",", false); 
      sb.append("on the following seconds: "); 
      int added = 0; 
      while(tokens.hasMoreTokens()){ 
       sb.append((added==0 ? "":", ") + tokens.nextToken());added++; 
      } 
     } 
    } 
    private static void humanizeMinutes(String value, StringBuffer sb){ 
     value=value.trim(); 
     if(STRING.isNumeric(value)){ 
      sb.append("the " + value + postFix(value) + " minute, "); 
     } 
     else if(value.equals("*")) 
     { 
      sb.append("every minute, "); 
     } 
     else if(value.indexOf("/")>-1){ 
      String first = value.substring(0, value.indexOf("/")); 
      String every = value.substring(value.indexOf("/") + 1); 
      sb.append("the " + first + postFix(first) + " minute and every " + every + " minute" + (Integer.parseInt(every) == 1 ? "":"s") + " following, "); 
     } 
     else if(value.indexOf("-")>-1){ 
      StringTokenizer tokens = new StringTokenizer(value, "-", false); 
      sb.append("for every minute from " + tokens.nextToken() + " through " + tokens.nextToken() + " "); 
     } 
     else if(value.indexOf(",")>-1){ 
      StringTokenizer tokens = new StringTokenizer(value, ",", false); 
      sb.append("the following minutes: "); 
      int added = 0; 
      while(tokens.hasMoreTokens()){ 
       sb.append((added==0 ? "":", ") + tokens.nextToken());added++; 
      } 
     } 
    } 
    private static void humanizeHours(String value, StringBuffer sb){ 
     value=value.trim(); 
     if(STRING.isNumeric(value)){ 
      sb.append("the " + value + postFix(value) + " hour, "); 
     } 
     else if(value.equals("*")) 
     { 
      sb.append("every hour, "); 
     } 
     else if(value.indexOf("/")>-1){ 
      String first = value.substring(0, value.indexOf("/")); 
      String every = value.substring(value.indexOf("/") + 1); 
      sb.append("the " + first + postFix(first) + " hour and every " + every + " hour" + (Integer.parseInt(every) == 1 ? "":"s") + " following, "); 
     } 
     else if(value.indexOf("-")>-1){ 
      StringTokenizer tokens = new StringTokenizer(value, "-", false); 
      sb.append("for every hour from " + tokens.nextToken() + " through " + tokens.nextToken() + " "); 
     } 
     else if(value.indexOf(",")>-1){ 
      StringTokenizer tokens = new StringTokenizer(value, ",", false); 
      sb.append("the following hours: "); 
      int added = 0; 
      while(tokens.hasMoreTokens()){ 
       sb.append((added==0 ? "":", ") + tokens.nextToken());added++; 
      } 
     } 
    } 
    private static String postFix(String value){ 
     String post = null; 
      if(value.substring(value.length()-1).equals("1"))post = "st"; 
      else if(value.substring(value.length()-1).equals("2"))post = "nd"; 
      else if(value.substring(value.length()-1).equals("3"))post = "rd"; 
      else post="th"; 
     return post; 
    } 
} 
5

Tôi đã tạo một trang nhỏ để dịch cron. http://crontranslator.appspot.com/ Nó vẫn cần một số cải tiến, mọi đề xuất đều được hoan nghênh.

+0

Có phải mã nguồn mở không? –

+0

chưa có dự án nào trên mã google hoặc github. Nhưng nếu bạn muốn có một cái nhìn, nó chỉ là tập tin javascript trên trang. –

+0

tuyệt vời! nhưng tôi có thể sử dụng nó không? (tất nhiên, cho bạn tín dụng thích hợp) tôi có thể đặt nó ở đâu đó trên github? –

1

cron-utils có thể hữu ích cho công việc này, vì cung cấp giới thiệu có thể đọc được con người và không đòi hỏi một lịch trình đủ lông đủ cánh để cung cấp cho họ. Là tài liệu tốt và hỗ trợ nhiều định dạng cron.

Dưới đây là một đoạn mã từ các tài liệu:

//create a descriptor for a specific Locale 
CronDescriptor descriptor = CronDescriptor.instance(Locale.UK); 

//parse some expression and ask descriptor for description 
String description = descriptor.describe(parser.parse("*/45 * * * * *")); 
//description will be: "every 45 seconds"