StruggleLion
StruggleLion

Reputation: 99

Cron Expression is not working for last day of the month

I want to schedule a task to run on last day of every month at 10:10 AM. The cron expression is 0 10 10 L * ?

Now the problem is CronSequenceGenerator is throwing NumberFormatException for 'L' value. This means Spring's CronSequenceGenerator doesn't support this kind of expression. But if I am passing only passing numeric it is working fine.

Here is the full stacktrace:

Exception in thread "main" java.lang.NumberFormatException: For input string: "L"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:492)
at java.lang.Integer.valueOf(Integer.java:582)
at org.springframework.scheduling.support.CronSequenceGenerator.getRange(CronSequenceGenerator.java:324)
at org.springframework.scheduling.support.CronSequenceGenerator.setNumberHits(CronSequenceGenerator.java:297)
at org.springframework.scheduling.support.CronSequenceGenerator.setDays(CronSequenceGenerator.java:275)
at org.springframework.scheduling.support.CronSequenceGenerator.setDaysOfMonth(CronSequenceGenerator.java:266)
at org.springframework.scheduling.support.CronSequenceGenerator.parse(CronSequenceGenerator.java:239)
at org.springframework.scheduling.support.CronSequenceGenerator.<init>(CronSequenceGenerator.java:81)
at org.springframework.scheduling.support.CronTrigger.<init>(CronTrigger.java:54)
at org.springframework.scheduling.support.CronTrigger.<init>(CronTrigger.java:44)
at com.hcdc.coedp.datantar.scheduler.SchedulerUtil.start(SchedulerUtil.java:75)
at com.hcdc.coedp.datantar.scheduler.SchedulerUtil.changeTrigger(SchedulerUtil.java:106)
at com.hcdc.coedp.datantar.scheduler.SchedulingService.scheduleTransfer(SchedulingService.java:70)
at com.hcdc.coedp.datantar.scheduler.Scheduler.schedule(Scheduler.java:107)     
at main.Main.main(Main.java:47)

Upvotes: 1

Views: 13580

Answers (5)

yglodt
yglodt

Reputation: 14551

Update for Spring 5.3

Spring now supports the following syntax to run on the last day of the month

@Scheduled(cron = "0 0 0 L * *") // last day of the month at midnight

Original answer:

This Schedule runs on the last day of the month an 10:10AM:

@Scheduled(cron = "0 10 10 28-31 * ?")
public void doStuffOnLastDayOfMonth() {
    final Calendar c = Calendar.getInstance();
    if (c.get(Calendar.DATE) == c.getActualMaximum(Calendar.DATE)) {
        // do your stuff
    }
}

Upvotes: 20

yglodt
yglodt

Reputation: 14551

There is another possible approach, depending on what you want to do:

import org.apache.commons.lang3.time.DateUtils;

@Scheduled(cron = "0 0 0 1 * ?") // runs on the first day of each month
public void doStuffOnFirstDayOfMonth() {
    Date now = DateUtils.addDays(new Date(), -1); // "now" is now on the last day of the month
}

I use this to generate statistics for a month of data. The routine should run on the first day of the next month to be sure to capture all data of the full previous month.

While this does not answer the question in the sense of having a Cron Expression for the last day of the month, it still can be a solution for jobs which need to run for a full month and this as soon as possible after the month has come to an end.

Upvotes: 1

Paweł Głowacz
Paweł Głowacz

Reputation: 3046

Expression syntactically correct with your condition: 0 10 10 L 1/1 ? *

And this is workaround that you could be interested: Workaround for CronSequenceGenerator Last day of month?

Upvotes: -1

Olivier Gr&#233;goire
Olivier Gr&#233;goire

Reputation: 35437

The last day of the month is not supported by Spring. See CronSequenceGenerator's javadoc.

Upvotes: 1

Lathy
Lathy

Reputation: 887

Please check this link Cron Maker

Give your expression in the text box

0 10 10 L * ?

Upvotes: 1

Related Questions