2

Following to my previous question, I subclssed CronExpression and changed getSet to be public. this method gets int type, and i have a String containing the cron expression. How do I get the info about this expression (hour\days\etc) ? what do I need to pass to getSet method? or maybe I should use another method? this is very unclear for me.

Community
  • 1
  • 1
user590586
  • 2,960
  • 16
  • 63
  • 96

1 Answers1

4

The problem with CronExpression is that even though it states it:

Provides a parser and evaluator for unix-like cron expressions.

The API is obscure and hidden under protected methods. By far it is not a general-purpose CRON expression parser. However with a few tweaks you can easily take advantage of the parsing logic:

class MyCronExpression extends CronExpression {

    public MyCronExpression(String cronExpression) throws ParseException
    {
        super(cronExpression);
    }

    public TreeSet<Integer> getSeconds()
    {
        return super.getSet(CronExpression.SECOND);
    }

    public TreeSet<Integer> getMinutes()
    {
        return super.getSet(CronExpression.MINUTE);
    }

    public TreeSet<Integer> getHours()
    {
        return super.getSet(CronExpression.HOUR);
    }

    //...

}

Usage:

final MyCronExpression cronExpression = new MyCronExpression("0 30 9,12,15 * * ?");
System.out.println(cronExpression.getSeconds());        //0
System.out.println(cronExpression.getMinutes());        //30
System.out.println(cronExpression.getHours());      //9, 12, 15

You might be tempted to parse CRON expression manually using regular expressions... Here is a regex from job_scheduling_data_2_0.xsd Quartz schema:

(((([0-9]|[0-5][0-9]),)*([0-9]|[0-5][0-9]))|(([\*]|[0-9]|[0-5][0-9])(/|-)([0-9]|[0-5][0-9]))|([\?])|([\*]))[\s](((([0-9]|[0-5][0-9]),)*([0-9]|[0-5][0-9]))|(([\*]|[0-9]|[0-5][0-9])(/|-)([0-9]|[0-5][0-9]))|([\?])|([\*]))[\s](((([0-9]|[0-1][0-9]|[2][0-3]),)*([0-9]|[0-1][0-9]|[2][0-3]))|(([\*]|[0-9]|[0-1][0-9]|[2][0-3])(/|-)([0-9]|[0-1][0-9]|[2][0-3]))|([\?])|([\*]))[\s](((([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1]),)*([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1])(C)?)|(([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1])(/|-)([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1])(C)?)|(L(-[0-9])?)|(L(-[1-2][0-9])?)|(L(-[3][0-1])?)|(LW)|([1-9]W)|([1-3][0-9]W)|([\?])|([\*]))[\s](((([1-9]|0[1-9]|1[0-2]),)*([1-9]|0[1-9]|1[0-2]))|(([1-9]|0[1-9]|1[0-2])(/|-)([1-9]|0[1-9]|1[0-2]))|(((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]((([1-7],)*([1-7]))|([1-7](/|-)([1-7]))|(((MON|TUE|WED|THU|FRI|SAT|SUN),)*(MON|TUE|WED|THU|FRI|SAT|SUN)(C)?)|((MON|TUE|WED|THU|FRI|SAT|SUN)(-|/)(MON|TUE|WED|THU|FRI|SAT|SUN)(C)?)|(([1-7]|(MON|TUE|WED|THU|FRI|SAT|SUN))?(L|LW)?)|(([1-7]|MON|TUE|WED|THU|FRI|SAT|SUN)#([1-7])?)|([\?])|([\*]))([\s]?(([\*])?|(19[7-9][0-9])|(20[0-9][0-9]))?| (((19[7-9][0-9])|(20[0-9][0-9]))(-|/)((19[7-9][0-9])|(20[0-9][0-9])))?| ((((19[7-9][0-9])|(20[0-9][0-9])),)*((19[7-9][0-9])|(20[0-9][0-9])))?)

Or maybe someone knows a better general-purpose CRON expression parser for Java?

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • why when i print one of the parameters, for exmale: `System.out.println(cronExpression.getMinutes());` I don't get just the number 30, i get it like this: `[30]` ? is there a way to get it as an int? – user590586 Mar 15 '12 at 12:00
  • @user590586: it returns a `TreeSet` and this is how `toString()` is implemented... – Tomasz Nurkiewicz Mar 15 '12 at 12:08
  • so i have to do replaceAll? no other option? – user590586 Mar 15 '12 at 12:13
  • 1
    @user590586: OMG, this is a `Set`, a **set**, you can iterate over it, convert it to list, pick subset... – Tomasz Nurkiewicz Mar 15 '12 at 12:15
  • OMG, for some people this is their first time that they work with a `set`. got it to work, thank's. – user590586 Mar 15 '12 at 12:19
  • 1
    @user590586: no offence, sorry. It is just that you are working with a **very** comprehensive and advanced Java library and using a `Set` data structure is kind-of a basic Java. – Tomasz Nurkiewicz Mar 15 '12 at 12:22
  • 3
    Unfortunately, in the latest version of the Quartz API, the CronExpression class is "Final", so this workaround is now broken. – Fallso Feb 11 '14 at 11:38