人間が読める文字列へのCron [クローズ]
-
22-07-2019 - |
質問
JavaでQuartzを使用してジョブをスケジュールしています。一つのことは、cron式をデータベースに保存し、それらをユーザーに表示したいのですが、より読みやすい形式にすることです。だから私はcron式を人間が読める文字列に変換できるユーティリティがあるのだろうかと思っていました。次のようなもの:
"" 0 30 10-13? *水、金" となります "毎週水曜日と金曜日に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"
これは私が始めたものです。ユーザーが(おそらく)理解できる言語を使用します。
dayofmonthトークンの '1,13,16-23、L'のようなトークンの混合ではうまくいきませんが、うまくいけば、ユーザーが洗練されるまでそれを費やす時間があるでしょう:
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; } }
CronTriggerは、cron式StringからCronExpressionオブジェクトを作成します。 ただし、アクセスすることはできません。ただし、リフレクションを使用すると、次のことができます。
Class c = cronTrigger.getClass();
Field f = c.getDeclaredField("cronEx");
f.setAccessible(true);
CronExpression cronEx = (CronExpression) f.get(cronTrigger);