6月最后一天的CronSequenceGenerator工作?

时间:2022-10-16 09:31:51

Ok so here it is I want to schedule a task to run on last day of every month on 10:10 AM.My cron expression is

好的,我想要安排一个任务在每个月的最后一天早上10:10运行。我的cron表达式是

0 10 10 L * ?

Now the problem is CronSequenceGenerator is throwing NumberFormatException for 'L' value.This means Spring's CronSequenceGenerator does'nt support this kind of expression.How to do this in any other way (workaround).I don't want to use quartz or Does spring's gonna support this in new releases.

现在问题是CronSequenceGenerator为“L”值抛出NumberFormatException。这意味着Spring的CronSequenceGenerator不支持这种表达式。如何用其他方法来做这件事(变通)。我不想使用quartz,或者spring会在新版本中支持它。

Here is 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:

更新:

Following is my scheduling 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 NumberFormatException when I pass specified cron expression.

在第2行,当我传递指定的cron表达式时,它会抛出NumberFormatException。

3 个解决方案

#1


6  

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

该特性不在标准的cron表达式语法中。所以Spring可能永远不会实现它。查看代码,我看不到任何扩展CronSequenceGenerator的手术解决方案。为什么你不使用石英,因为它是一个特殊的特性?

Depending on your exact need, you could 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();
    }
}

#2


6  

As a workaround I would schedule the execution for all dates

作为一种变通方法,我会安排所有日期的执行。

0 10 10 * * ?

and checked the actual date in the scheduled method

并在预定的方法中检查实际日期。

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

#3


2  

Optimized version which runs only on the last day of a 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
    }
}

#1


6  

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

该特性不在标准的cron表达式语法中。所以Spring可能永远不会实现它。查看代码,我看不到任何扩展CronSequenceGenerator的手术解决方案。为什么你不使用石英,因为它是一个特殊的特性?

Depending on your exact need, you could 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();
    }
}

#2


6  

As a workaround I would schedule the execution for all dates

作为一种变通方法,我会安排所有日期的执行。

0 10 10 * * ?

and checked the actual date in the scheduled method

并在预定的方法中检查实际日期。

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

#3


2  

Optimized version which runs only on the last day of a 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
    }
}