私はJavaでQuartzを使用してジョブをスケジュールしています。1つは、cron式をデータベースに保存し、それらをユーザーに提示したいのですが、より読みやすい形式で表示したいということです。だから私はcron式を人間が読める文字列に変換できるユーティリティがあるかどうか疑問に思いました。何かのようなもの :
"" 0 30 10-13?* WED、FRI」は「毎週水曜日と金曜日の10:30、11:30、12:30、13:30に火災」になります。
私はJavaでQuartzを使用してジョブをスケジュールしています。1つは、cron式をデータベースに保存し、それらをユーザーに提示したいのですが、より読みやすい形式で表示したいということです。だから私はcron式を人間が読める文字列に変換できるユーティリティがあるかどうか疑問に思いました。何かのようなもの :
"" 0 30 10-13?* WED、FRI」は「毎週水曜日と金曜日の10:30、11:30、12:30、13:30に火災」になります。
cron式を人間が読める文字列に変換するJavaライブラリ:https ://github.com/RedHogs/cron-parser
はい、私はあなたの質問を理解しました。しかし、私は私の答えをもう少しよく説明するべきでした。
いいえ、「人間」が読める形式でcron式を取得するのに役立つツールはわかりません。しかし、CronExpressionにアクセスすることで、自分で作成することができます。
電話してみてください
cronTrigger.getExpressionSummary()
cron式について:
"0/2 * * 4 * ?"
次の文字列を返します。
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: *
CronExpressionオブジェクトにアクセスすることで、独自の「人間」の説明を作成できます。
cron-utilsは、人間が読める形式の説明を提供し、それらを提供するために本格的なスケジューラを必要としないため、このタスクに役立つ場合があります。十分に文書化されており、複数のcron形式をサポートしています。
ドキュメントのコードスニペットの下:
//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"
これが私が始めたものです。それは私のユーザーが(おそらく)理解するであろう言語を使用します。
その日のトークンの「1,13,16-23、L」のようなトークンの混合ではうまくいきませんが、うまくいけば、ユーザーがそれほど洗練される前に、それに費やす時間があります:
パッケージcom.tacteonltd.control.cron; インポートjava.util.StringTokenizer; インポートcom.tacteonltd.control.string.STRING; インポートcom.tacteonltd.control.time.TIME; パブリッククラスCRON{ public static String humanReadable(String value){ StringBuffer sb = new StringBuffer(); 試す{ 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"); 文字列dom=tokens.nextToken(); 文字列month=tokens.nextToken(); 文字列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(); } sb.toString();を返します。 } private static void humanizeDOWs(String value、String dom、StringBuffer sb){ value = value.trim(); if(STRING.isNumeric(value)){ sb.append("および"+ value + postFix(value)+ "day-of-the-week(" + TIME.getWeekDayName(Integer.parseInt(value))+ ")。"); } else if(value.equals( "*")) {{ sb.append( "および毎日。"); } else if(value.equals( "?")) {{ sb.append("およびその日の曜日は何でも"+(STRING.isNumeric(dom)? "": "s")+ "-of-the-month:" +(STRING.isNumeric (dom)?dom: "that match" +(STRING.isNumeric(dom)? "es": "")+ "" + dom + "。")); } else if(value.indexOf( "/")>-1){ 最初の文字列=value.substring(0、value.indexOf( "/")); 文字列every=value.substring(value.indexOf( "/")+ 1); sb.append("and" + first + postFix(first)+ "day-of-the-week and every" + every + "day" +(Integer.parseInt(every)== 1? "": "s ")+"フォロー中。 "); } else if(value.indexOf( "、")>-1){ StringTokenizer tokens = new StringTokenizer(value、 "、"、false); sb.append( "および次の曜日:"); intが追加されました=0; while(tokens.hasMoreTokens()){ 文字列token=tokens.nextToken(); sb.append((added == 0? "": "、")+トークン);追加++; } sb.append( "。"); } else if(value.indexOf( "-")>-1){ StringTokenizer tokens = new StringTokenizer(value、 "-"、false); sb.append("および"+ tokens.nextToken()+"から" + tokens.nextToken()+ "。"までの毎日); } そうしないと { sb.append( "および次の曜日:" + value + "。"); } } private static void humanizeMonths(String value、StringBuffer sb){ value = value.trim(); if(STRING.isNumeric(value)){ sb.append( "" + value + postFix(value)+ "month(" + TIME.getMonthName(Integer.parseInt(value))+ ")、"); } else if(value.equals( "*")) {{ sb.append( "毎月、"); } else if(value.indexOf( "/")>-1){ 最初の文字列=value.substring(0、value.indexOf( "/")); 文字列every=value.substring(value.indexOf( "/")+ 1); sb.append( "" "+ first + postFix(first)+" month( "+ TIME.getMonthName(Integer.parseInt(value))+")およびevery "+ every +" month "+(Integer.parseInt(every )== 1? "": "s")+ "following、"); } else if(value.indexOf( "、")>-1){ StringTokenizer tokens = new StringTokenizer(value、 "、"、false); sb.append( "次の月:"); intが追加されました=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( "" + value + postFix(value)+ "day-of-the-month、"); } else if(value.equals( "*")) {{ sb.append( "毎月の毎日、"); } else if(value.equals( "?")) {{ sb.append("月のどの日が当たっても"+ dow + "、"); } else if(value.indexOf( "-")>-1){ StringTokenizer tokens = new StringTokenizer(value、 "-"、false); 文字列from=tokens.nextToken(); 文字列から=tokens.nextToken(); int year = TIME.getYear(System.currentTimeMillis()); int month = TIME.getMonth(System.currentTimeMillis()); 文字列last_dom="" + TIME.getLastDOM(year、month); sb.append("月の毎日"+ from +"から"+(through.equals( "L")? "last(" + year+"。"+month+"。"+last_dom + " )":終えた) ); } else if(value.indexOf( "/")>-1){ 最初の文字列=value.substring(0、value.indexOf( "/")); 文字列every=value.substring(value.indexOf( "/")+ 1); sb.append( "" + first + postFix(first)+ "day-of-the-month and every" + every + "day" +(Integer.parseInt(every)== 1? "": "s" )+ "フォロー中、"); } else if(value.indexOf( "、")>-1){ StringTokenizer tokens = new StringTokenizer(value、 "、"、false); sb.append( "その月の次の日:"); intが追加されました=0; while(tokens.hasMoreTokens()){ 文字列token=tokens.nextToken(); if(token.equals( "L")){ int year = TIME.getYear(System.currentTimeMillis()); int month = TIME.getMonth(System.currentTimeMillis()); 文字列last_dom="" + TIME.getLastDOM(year、month); sb.append((added == 0? "": "、")+ "the last(" + year+"。"+month+"。"+last_dom + ")"); } そうしないと{ sb.append((added == 0? "": "、")+トークン);追加++; } } } } private static void humanizeSeconds(String value、StringBuffer sb){ value = value.trim(); if(STRING.isNumeric(value)){ sb.append( "on" + value + postFix(value)+ "second、"); } else if(value.equals( "*")) {{ sb.append( "毎秒、"); } else if(value.indexOf( "/")>-1){ 最初の文字列=value.substring(0、value.indexOf( "/")); 文字列every=value.substring(value.indexOf( "/")+ 1); sb.append( "on" + 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("毎秒"+ tokens.nextToken()+"から" + tokens.nextToken()+ ""); } else if(value.indexOf( "、")>-1){ StringTokenizer tokens = new StringTokenizer(value、 "、"、false); sb.append( "次の秒に:"); intが追加されました=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( ""+値+postFix(値)+ "分、"); } else if(value.equals( "*")) {{ sb.append( "毎分、"); } else if(value.indexOf( "/")>-1){ 最初の文字列=value.substring(0、value.indexOf( "/")); 文字列every=value.substring(value.indexOf( "/")+ 1); sb.append( "" + 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("毎分"+ tokens.nextToken()+"から" + tokens.nextToken()+ ""); } else if(value.indexOf( "、")>-1){ StringTokenizer tokens = new StringTokenizer(value、 "、"、false); sb.append( "次の分:"); intが追加されました=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( ""+値+postFix(値)+ "時間、"); } else if(value.equals( "*")) {{ sb.append( "毎時、"); } else if(value.indexOf( "/")>-1){ 最初の文字列=value.substring(0、value.indexOf( "/")); 文字列every=value.substring(value.indexOf( "/")+ 1); sb.append( "" + 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("毎時"+ tokens.nextToken()+"から" + tokens.nextToken()+ ""); } else if(value.indexOf( "、")>-1){ StringTokenizer tokens = new StringTokenizer(value、 "、"、false); sb.append( "次の時間:"); intが追加されました=0; while(tokens.hasMoreTokens()){ sb.append((added == 0? "": "、")+ tokens.nextToken()); added ++; } } } プライベート静的文字列postFix(文字列値){ 文字列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"; リターンポスト; } }
CronTriggerは、cron式StringからCronExpressionオブジェクトを作成します。しかし、あなたはそれにアクセスすることはできません。しかし、リフレクションを使用すると、次のことができます。
Class c = cronTrigger.getClass();
Field f = c.getDeclaredField("cronEx");
f.setAccessible(true);
CronExpression cronEx = (CronExpression) f.get(cronTrigger);