2009-08-05 12 views
12

Ich verwende Quartz mit Java, um Jobs zu planen. Eine Sache ist, dass ich Cron-Ausdrücke in einer Datenbank speichere und ich möchte sie einem Benutzer präsentieren, aber in einer besser lesbaren Form. Also habe ich mich gefragt, ob es ein Dienstprogramm gibt, das einen Cron-Ausdruck in eine vom Menschen lesbare Zeichenfolge konvertieren könnte. Etwas wie:Cron zu lesbaren Zeichenfolge

"" 0 30 10-13? * WED, FRI Fires um 10:30, 11:30, 12:30 und 13:30, jeden Mittwoch und Freitag“ wird werden ""

+4

Haben Sie schon einmal eine schöne Lösung implementieren? Ich muss genau dasselbe tun, hast du irgendwelche Hinweise/Strategien, die meine Implementierung erleichtern? –

+0

Ich fürchte nicht ... Dies wurde für die Produktion benötigt und meine Firma sah es nicht als Priorität. Stattdessen entschieden wir uns, einfach die nächste Feuerzeit für die Cron-Jobs anzuzeigen: S Aber die Antwort, die ich unten akzeptiert habe, bietet einen Ausgangspunkt für die Arbeit mit Cron. Ich weiß nicht, wie einfach es wäre ... –

Antwort

19

Eine Java-Bibliothek, die cron Ausdrücke in für Menschen lesbaren Zeichenketten konvertiert: https://github.com/RedHogs/cron-parser

+12

Ich liebe es, dass Stackoverflow auch nach 5 Jahren die richtige Antwort auf eine Frage liefert. :) Prost –

0

Die CronTrigger schafft ein CronExpression Objekt aus dem Cron-Ausdruck . String Aber man kann keinen Zugriff darauf erhalten, aber durch Reflexion verwenden Sie können:.

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

Ich denke, du hast meine Frage nicht verstanden –

9

Nun ja habe ich verstehe Ihre Frage Aber ich sollte meine Antwort ein wenig besser erklärt haben

Nein, ich.. Ich kenne kein Werkzeug, das Ihnen hilft, einen Cron-Ausdruck in "menschlich" lesbarer Form zu bekommen Zugriff auf die CronExpression können Sie selbst erstellen.

Try

cronTrigger.getExpressionSummary() 

auf dem Cron-Ausdruck Aufruf:

"0/2 * * 4 * ?" 

es gibt die folgende Zeichenfolge:

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: * 

Durch Zugriff auf das CronExpression Objekt haben, können Sie erstellen Ihre eigene "menschliche" Erleuchtung.

+0

ja danke für die Antwort. Es scheint, dass ich meine Version erstellen werde. –

2

hier ist eine ich begann. Es verwendet die Sprache, die meine Benutzer (wahrscheinlich) verstehen werden.

es wird nicht so gut mit Mischungen von Token wie '1,13,16-23, L' für den Tag des Monats Token, aber hoffentlich habe ich etwas Zeit, um es zu verbringen, bevor meine Benutzer das werden raffiniert:

 
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

Ich machte eine kleine Seite für Cron-Übersetzung. http://crontranslator.appspot.com/ Es bedarf noch einiger Verbesserungen, Anregungen sind willkommen.

+0

Ist es Open Source? –

+0

Es gibt noch kein Projekt auf Google Code oder Github. Aber wenn Sie einen Blick darauf werfen wollen, ist es nur Javascript-Datei auf der Seite. –

+0

cool! aber kann ich es benutzen? (Natürlich, um Ihnen einen guten Kredit zu geben) Kann ich es irgendwo auf Github setzen? –

1

cron-utils kann für diese Aufgabe nützlich sein, da Menschen lesbare Beschreibungen liefert und erfordert keinen vollwertigen Scheduler sie zu sorgen. Ist gut dokumentiert und unterstützt mehrere Cron-Formate.

Unterhalb eines Code-Schnipsel aus der Dokumentation:

//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" 
Verwandte Themen