I'm writing a scheduling application in Java using Quartz. I'm using the CronTrigger, but my cron expressions are entered into a database before they are scheduled and are based on user input.
Is there a way I can verify that the cron expressions are valid when I capture them? I'd rather do this and give the user an appropriate error message than wait until the scheduler is run and I get a ParseException when I try and create the trigger. Which could be days after the user inputs the data.
“0 0 12 * * ?” means “At noon every day”. “0 30 21 ? * *” means “At 9:30pm every day”.
CronSequenceGenerator; final String cronExpression = "0 45 23 * * *"; final CronSequenceGenerator generator = new CronSequenceGenerator(cronExpression); final Date nextExecutionDate = generator. next(new Date()); ...and then I suggest use Joda DateTime for date comparison.
A Cron is a time-based job scheduler. It enables our application to schedule a job to run automatically at a certain time or date. A Job (also known as a Task) is any module that you wish to run.
Can't you simply create a trigger without actually executing it? You could simply give appropriate feedback in case of a ParseException. If the expression is okay, persist the expression to DB.
Edit: or simply do this:
org.quartz.CronExpression.isValidExpression(expression);
I've modified the following code added by @ph4r05 to generate a regex as well; here's the regex:
^\s*($|#|\w+\s*=|(\?|\*|(?:[0-5]?\d)(?:(?:-|\/|\,)(?:[0-5]?\d))?(?:,(?:[0-5]?\d)(?:(?:-|\/|\,)(?:[0-5]?\d))?)*)\s+(\?|\*|(?:[0-5]?\d)(?:(?:-|\/|\,)(?:[0-5]?\d))?(?:,(?:[0-5]?\d)(?:(?:-|\/|\,)(?:[0-5]?\d))?)*)\s+(\?|\*|(?:[01]?\d|2[0-3])(?:(?:-|\/|\,)(?:[01]?\d|2[0-3]))?(?:,(?:[01]?\d|2[0-3])(?:(?:-|\/|\,)(?:[01]?\d|2[0-3]))?)*)\s+(\?|\*|(?:0?[1-9]|[12]\d|3[01])(?:(?:-|\/|\,)(?:0?[1-9]|[12]\d|3[01]))?(?:,(?:0?[1-9]|[12]\d|3[01])(?:(?:-|\/|\,)(?:0?[1-9]|[12]\d|3[01]))?)*)\s+(\?|\*|(?:[1-9]|1[012])(?:(?:-|\/|\,)(?:[1-9]|1[012]))?(?:L|W)?(?:,(?:[1-9]|1[012])(?:(?:-|\/|\,)(?:[1-9]|1[012]))?(?:L|W)?)*|\?|\*|(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(?:(?:-)(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?(?:,(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(?:(?:-)(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?)*)\s+(\?|\*|(?:[0-6])(?:(?:-|\/|\,|#)(?:[0-6]))?(?:L)?(?:,(?:[0-6])(?:(?:-|\/|\,|#)(?:[0-6]))?(?:L)?)*|\?|\*|(?:MON|TUE|WED|THU|FRI|SAT|SUN)(?:(?:-)(?:MON|TUE|WED|THU|FRI|SAT|SUN))?(?:,(?:MON|TUE|WED|THU|FRI|SAT|SUN)(?:(?:-)(?:MON|TUE|WED|THU|FRI|SAT|SUN))?)*)(|\s)+(\?|\*|(?:|\d{4})(?:(?:-|\/|\,)(?:|\d{4}))?(?:,(?:|\d{4})(?:(?:-|\/|\,)(?:|\d{4}))?)*))$
Here's the java code:
private static String cronRegex = null; public static String getCronRegex() { if (cronRegex == null) { // numbers intervals and regex Map<String, String> numbers = new HashMap<String, String>(); numbers.put("sec", "[0-5]?\\d"); numbers.put("min", "[0-5]?\\d"); numbers.put("hour", "[01]?\\d|2[0-3]"); numbers.put("day", "0?[1-9]|[12]\\d|3[01]"); numbers.put("month", "[1-9]|1[012]"); numbers.put("dow", "[0-6]"); numbers.put("year", "|\\d{4}"); Map<String, String> field_re = new HashMap<String, String>(); // expand regex to contain different time specifiers for (String field : numbers.keySet()) { String number = numbers.get(field); String range = "(?:" + number + ")(?:(?:-|\\/|\\," + ("dow".equals(field)? "|#" : "") + ")(?:" + number + "))?" + ("dow".equals(field)? "(?:L)?" : ("month".equals(field)? "(?:L|W)?" : "")); field_re.put(field, "\\?|\\*|" + range + "(?:," + range + ")*"); } // add string specifiers String monthRE = field_re.get("month"); String monthREVal = "JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC"; String monthRERange = "(?:" + monthREVal + ")(?:(?:-)(?:" + monthREVal + "))?" ; monthRE = monthRE + "|\\?|\\*|" + monthRERange + "(?:," + monthRERange + ")*" ; field_re.put("month", monthRE); String dowRE = field_re.get("dow"); String dowREVal = "MON|TUE|WED|THU|FRI|SAT|SUN"; String dowRERange = "(?:" + dowREVal + ")(?:(?:-)(?:" + dowREVal + "))?" ; dowRE = dowRE + "|\\?|\\*|" + dowRERange + "(?:," + dowRERange + ")*" ; field_re.put("dow", dowRE); StringBuilder fieldsReSB = new StringBuilder(); fieldsReSB.append("^\\s*(").append("$") // .append("|#") // .append("|\\w+\\s*=") // .append("|") // .append("(")// .append(field_re.get("sec")).append(")\\s+(")// .append(field_re.get("min")).append(")\\s+(")// .append(field_re.get("hour")).append(")\\s+(")// .append(field_re.get("day")).append(")\\s+(")// .append(field_re.get("month")).append(")\\s+(")// .append(field_re.get("dow")).append(")(|\\s)+(")// .append(field_re.get("year"))// .append(")")// .append(")")// .append("$"); cronRegex = fieldsReSB.toString(); } return cronRegex; }
I'm by no means a regex expert, but at least this seems to work on all the examples given by the quartz documentation
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With