Running Linux-like Crons in Java


This doesn’t handle improper input, but it works for proper input. I use it on a Spring MVC Scheduled Task that runs every minute to dynamically pull Report Schedules from the database and check if they should run at that minute.

    /*
     *  Linux Crons *
        field          allowed values  (ex:  *  1  1,5   1-5   * /5)
        -----          --------------
        minute         0-59  
        hour           0-23
        day of month   1-31
        month          1-12 
        day of week    0-7 (0 or 7 is Sun)
     */
    private boolean cronMatch(Calendar now, ReportSchedule schedule) {
        boolean match = false;
        
        int minuteToMatch = now.get(Calendar.MINUTE);
        int hourToMatch = now.get(Calendar.HOUR_OF_DAY);
        int dayOfMonthToMatch = now.get(Calendar.DAY_OF_MONTH);
        int monthToMatch = now.get(Calendar.MONTH) + 1;
        int dayOfWeekToMatch = now.get(Calendar.DAY_OF_WEEK) - 1;

        if(match(minuteToMatch, schedule.getMinute())) {
            if(match(hourToMatch, schedule.getHour())) {
                if(match(dayOfMonthToMatch, schedule.getDayOfMonth())) {
                    if(match(monthToMatch, schedule.getMonth())) {
                        if(match(dayOfWeekToMatch, schedule.getDayOfWeek())) {
                            match = true;
                        }
                    }
                }
            }
        }
        return match;
    }
    
    private boolean match(int value, String string) {
        boolean match = false;
        if(string == null) {
            return false;
        }
        if(string.trim().isEmpty()) {
            return false;
        }
        
        // Possible formats: */5    4-5    *     1    1,15,3
        try {
            if(string.equalsIgnoreCase("*")) {
                match = true;
            } else if(string.contains("/")) {
                String[] values = string.split("/");
                if(values.length == 2) {
                    int lower = Integer.parseInt(values[1]);
                    if(value % lower == 0) {
                        match = true;
                    }
                }
            } else if(string.contains("-")) {
                String[] values = string.split("-");
                if(values.length == 2) {
                    int lower = Integer.parseInt(values[0]);
                    int upper = Integer.parseInt(values[1]);
                    if(value >= lower && value <= upper) {
                        match = true;
                    }
                }
            } else if(string.contains(",")) {
                boolean found = false;
                String[] values = string.split(",");
                for(String val : values) {
                    int amount = Integer.parseInt(val);
                    if(amount == value) {
                        found = true;
                        break;
                    }
                }
                match = found;
            } else {
                int val = Integer.parseInt(string);
                if(value == val) {
                    match = true;
                }
            }
        } catch(Exception ex) {
            match = false;
        }
        
        return match;
    }
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s