Workaround for CronSequenceGenerator Last day of the month?

Well, here I want to schedule a task to be completed on the last day of every month at 10:10 AM. My cron expression

0 10 10 L * ? 

Now the CronSequenceGenerator problem throws a NumberFormatException for the value L. This means Spring CronSequenceGenerator does not support this kind of expression. How to do this in any other way (workaround). I do not want to use quartz or support Spring in new releases.

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) 

Update:

Below is my planning method

  /** * Schedule a task {@link Task} with a specified cron expression. * @param task {@link Task} * @param cronExpression cron expression to be applied must be a vaild one. * @param taskName * @return */ public String start(Task task, String cronExpression, String taskName) { CronTrigger trigger = new CronTrigger(cronExpression);//line 2 CronSequenceGenerator generator = new CronSequenceGenerator(cronExpression, TimeZone.getTimeZone("GMT+5:30")); List<Date> dateList = new ArrayList<>(5); Date currentDate = new Date(); for (int i = 0; i < 5; i++) { currentDate = generator.next(currentDate); dateList.add((currentDate)); System.out.println("Next Exceution times are" + currentDate); } ScheduledFuture sf = tps.schedule(task, trigger); //TODO Save this scheduled future with a specific task name. ContextHolder.schduledFutureMap.put(taskName, sf); return cronExpression; } 

And on line 2, it throws a NumberFormatException when passing the specified cron expression.

+7
java spring spring-mvc scheduled-tasks cronexpression
source share
3 answers

This function is not in the standard cron expression syntax . Spring will probably never implement it. Looking at the code , I don't see any surgical solution extending the CronSequenceGenerator . So why don't you just use Quartz as this is a special feature ?

Depending on your specific need, you can implement your own Trigger . Something like:

 import java.util.Date; import org.joda.time.LocalDate; import org.joda.time.LocalTime; import org.springframework.scheduling.Trigger; import org.springframework.scheduling.TriggerContext; public class LastDayOfMonthTrigger implements Trigger { private final LocalTime time; public LastDayOfMonthTrigger(LocalTime time) { this.time = time; } @Override public Date nextExecutionTime(TriggerContext ctx) { Date last = ctx.lastScheduledExecutionTime(); LocalDate date = last == null ? new LocalDate() : new LocalDate(last).plusDays(1); LocalDate lastDay = date.dayOfMonth().withMaximumValue(); return lastDay.toDateTime(time).toDate(); } } 
+6
source share

As a workaround, I plan to execute for all dates

 0 10 10 * * ? 

and checked the actual date in the planned method

 public void scheduledTask() { Calendar c = Calendar.getInstance(); if (c.get(Calendar.DATE) == c.getActualMaximum(Calendar.DATE)) { ... } } 
+6
source share

An optimized version that runs only on the last day of the month:

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

All Articles