Кварцевый хрон - что если дня месяца не существует? - PullRequest
5 голосов
/ 19 декабря 2011

Я пытаюсь написать простое выражение cron для кварцевого планировщика.Я хочу, чтобы работа выполнялась каждый месяц в день 30 в 3 часа утра.

0 0 3 30 JAN-DEC ? *

Интересно, что происходит в феврале?Будет ли задание выполняться или не запускаться?

Я не ищу решение на последний день месяца, мне нужно, чтобы пользователь выбрал день месяца, когда задание будет выполняться (в идеале, один раз для всех месяцев).

Ответы [ 4 ]

4 голосов
/ 19 декабря 2011

L («последний») - имеет различное значение в каждом из двух полей, в которых это разрешено.Например, значение «L» в поле дня месяца означает «последний день месяца» - 31 день для января, 28 день для февраля для не високосных лет.Если оно используется в поле дня недели само по себе, оно просто означает «7» или «SAT».Но если используется в поле дня недели после другого значения, это означает «последний xxx день месяца» - например, «6L» означает «последняя пятница месяца».При использовании опции 'L' важно не указывать списки или диапазоны значений, поскольку вы получите непонятные результаты.

Вы можете использовать это, чтобы указать вместо указания 30 в вашем задании кукурузы напрямую.

http://www.quartz -scheduler.org / документация / quartz-1.x / руководства / crontrigger

Проверка специальных символов.

Спасибо.

1 голос
/ 12 октября 2014

Это не будет работать.Если вы хотите, чтобы он работал 28-го числа в случае февраля, вы должны создать несколько CronExpressions для каждого случая дней в месяце и триггер для каждого, а затем добавить все триггеры в требуемое задание.

Вот что я сделал:

Создание CronExpressions:

public static List<CronExpression> getCronExpressionList(int seconds, int minutes,
            int hours, int dayInMonth, Month month,
            DayOfWeek dayOfWeek) {
    final String monthsWith30Days = Month.APR + "," + Month.JUN + ","
                    + Month.SEP + "," + Month.NOV;
    List<CronExpression> crons = new LinkedList<CronExpression>();

    String timeString = String.format(("%s %s %s "), seconds, minutes,
                    hours, 0, 0, 0);
    String dateString = "%s %s %s";
    String cron = null;

    cron = timeString + String.format(dateString, dayInMonth, "*", "?");
    crons.add(new CronExpression(cron));
    if (dayInMonth > 28) {
        String febCron = timeString + getFebruarLastDayDateString(dateString);
        crons.add(new CronExpression(febCron));
        if (dayInMonth == 31) {
            String monthsWithThirtyDaysCron = timeString + String.format(dateString,
                    "L", monthsWith30Days, "?");
            crons.add(new CronExpression(monthsWithThirtyDaysCron));
        }
    }
    return crons;
}

private static String getFebruarLastDayDateString(String initialCron) 
               throws ParseException {
    return String.format(initialCron, "L", Month.FEB, "?");
}

Создание триггера:

        Set<CronTrigger> triggers = new HashSet<>();

        int i = 1;
        for (CronExpression cronEx : cronsList) {
            CronTrigger trigger = newTrigger()
                    .withIdentity("trigger" + i, groupName)
                    .withSchedule(cronSchedule(cronEx))
                    .build();
                triggers.add(trigger);
                i++;
        }
0 голосов
/ 14 июня 2019

Приведенный ниже код вычисляет дату следующего пожара в последний день каждого месяца

static Date getNextFireTimeFromDateForCron() throws ParseException {
    CronTriggerImpl cronTrigger = new CronTriggerImpl();
    cronTrigger.setCronExpression("0 15 15 L * ?");
    cronTrigger.setStartTime(new Date());
    return cronTrigger.computeFirstFireTime(null);
}
0 голосов
/ 26 октября 2014

отметьте простой код

public class TestCronTrigger {

    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");

    public static void main(String[] args) throws Exception {

        String dateStr = "2015-02-10";
        String cron = "0 0 0 31 * ?";
        Date nextFireTime = getNextFireTimeFromDateForCron(DATE_FORMAT.parse(dateStr), cron);
        System.out.println(String.format("For cron '%s' next fire time after '%s' will be '%s'", cron, dateStr, DATE_FORMAT.format(nextFireTime)));

        dateStr = "2015-02-10";
        cron = "0 0 0 30 * ?";
        nextFireTime = getNextFireTimeFromDateForCron(DATE_FORMAT.parse(dateStr), cron);
        System.out.println(String.format("For cron '%s' next fire time after '%s' will be '%s'", cron, dateStr, DATE_FORMAT.format(nextFireTime)));

        dateStr = "2015-02-10";
        cron = "0 0 0 28 * ?";
        nextFireTime = getNextFireTimeFromDateForCron(DATE_FORMAT.parse(dateStr), cron);
        System.out.println(String.format("For cron '%s' next fire time after '%s' will be '%s'", cron, dateStr, DATE_FORMAT.format(nextFireTime)));

        dateStr = "2015-03-10";
        cron = "0 0 0 31 * ?";
        nextFireTime = getNextFireTimeFromDateForCron(DATE_FORMAT.parse(dateStr), cron);
        System.out.println(String.format("For cron '%s' next fire time after '%s' will be '%s'", cron, dateStr, DATE_FORMAT.format(nextFireTime)));

    }

    static Date getNextFireTimeFromDateForCron(Date from, String cron) throws ParseException {
        CronTriggerImpl cronTrigger = new CronTriggerImpl();
        cronTrigger.setCronExpression(cron);
        cronTrigger.setStartTime(from);
        return cronTrigger.computeFirstFireTime(null);
    }
}

Для этого кода вывод будет:

For cron '0 0 0 31 * ?' next fire time after '2015-02-10' will be '2015-03-31'
For cron '0 0 0 30 * ?' next fire time after '2015-02-10' will be '2015-03-30'
For cron '0 0 0 28 * ?' next fire time after '2015-02-10' will be '2015-02-28'
For cron '0 0 0 31 * ?' next fire time after '2015-03-10' will be '2015-03-31'

играя с аргументами, вы можете найти ответы

...