Java CronSequenceGenerator的解决方案是每月的最后一天?
好的,我想安排一个任务在每个月的最后一天上午10:10运行Java CronSequenceGenerator的解决方案是每月的最后一天?,java,spring,spring-mvc,scheduled-tasks,cronexpression,Java,Spring,Spring Mvc,Scheduled Tasks,Cronexpression,好的,我想安排一个任务在每个月的最后一天上午10:10运行 0 10 10 L * ? 现在的问题是为“L”值抛出NumberFormatException。这意味着Spring的CronSequenceGenerator不支持这种表达式。如何以任何其他方式做到这一点(解决方法)。我不想使用quartz,或者Spring会在新版本中支持这一点 以下是完整的stacktrace: Exception in thread "main" java.lang.NumberFormatException
0 10 10 L * ?
现在的问题是为“L”值抛出NumberFormatException。这意味着Spring的CronSequenceGenerator不支持这种表达式。如何以任何其他方式做到这一点(解决方法)。我不想使用quartz,或者Spring会在新版本中支持这一点
以下是完整的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)
线程“main”java.lang.NumberFormatException中的异常:对于输入字符串:“L”
位于java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
位于java.lang.Integer.parseInt(Integer.java:492)
位于java.lang.Integer.valueOf(Integer.java:582)
位于org.springframework.scheduling.support.CronSequenceGenerator.getRange(CronSequenceGenerator.java:324)
位于org.springframework.scheduling.support.CronSequenceGenerator.setNumberHits(CronSequenceGenerator.java:297)
位于org.springframework.scheduling.support.CronSequenceGenerator.setDays(CronSequenceGenerator.java:275)
位于org.springframework.scheduling.support.CronSequenceGenerator.setDaysOfMonth(CronSequenceGenerator.java:266)
位于org.springframework.scheduling.support.CronSequenceGenerator.parse(CronSequenceGenerator.java:239)
位于org.springframework.scheduling.support.CronSequenceGenerator(CronSequenceGenerator.java:81)
位于org.springframework.scheduling.support.CronTrigger.(CronTrigger.java:54)
位于org.springframework.scheduling.support.CronTrigger.(CronTrigger.java:44)
位于com.hcdc.coedp.datantar.SchedulerUtil.start(SchedulerUtil.java:75)
位于com.hcdc.coedp.datantar.SchedulerUtil.changeTrigger(SchedulerUtil.java:106)
位于com.hcdc.coedp.datantar.scheduler.SchedulingService.scheduleTransfer(SchedulingService.java:70)
位于com.hcdc.coedp.datantar.scheduler.scheduler.schedule(scheduler.java:107)
在main.main.main(main.java:47)
更新:
以下是我的日程安排方法
/**
* 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;
}
/**
*使用指定的cron表达式计划任务{@link task}。
*@param task{@link task}
*@param cronExpression要应用的cron表达式必须是有效的。
*@param taskName
*@返回
*/
公共字符串开始(任务任务、字符串表达式、字符串任务名){
CronTrigger=新的CronTrigger(cronExpression);//第2行
CronSequenceGenerator=新的CronSequenceGenerator(cronExpression,TimeZone.getTimeZone(“GMT+5:30”);
列表日期列表=新的ArrayList(5);
日期currentDate=新日期();
对于(int i=0;i<5;i++){
currentDate=发电机。下一个(currentDate);
添加((当前日期));
System.out.println(“下一个执行时间为“+当前日期”);
}
ScheduledFuture sf=tps.schedule(任务、触发器);
//TODO使用特定任务名称保存此计划的未来。
ContextHolder.scheduledfuturemap.put(taskName,sf);
返回表达式;
}
在第2行,当我传递指定的cron表达式时,它抛出NumberFormatException。作为一种解决方法,我将为所有日期安排执行
0 10 10 * * ?
并检查计划方法中的实际日期
public void scheduledTask() {
Calendar c = Calendar.getInstance();
if (c.get(Calendar.DATE) == c.getActualMaximum(Calendar.DATE)) {
...
}
}
此功能不在系统中。所以Spring可能永远不会实现它。查看,我看不到任何外科手术解决方案扩展CronSequenceGenerator
。既然石英是一种特殊材料,为什么不使用它呢
根据您的具体需要,您可以实现自己的。比如:
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();
}
}
仅在每月最后一天运行的优化版本:
@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
}
}
还有另一个解决方案: 生成一个月的数据。该程序应在下个月的第一天运行,以确保捕获整个月的所有数据
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
}
我环顾了一下四周,似乎我真的得到了支持。你如何定义这份工作?注释?您可能应该将此添加到问题中。@Magnilex check UpdateGrat。您还可以粘贴调用
start()
方法的相关代码吗?对此我很抱歉,但我真的认为使用L
应该可以工作。实际上,这不会影响输出,您可以在一个简单的主程序中测试它,只要在start方法中用“L”传递cron表达式,您就会得到异常。@Magnilex:我正在查看,我不明白为什么您认为它必须工作。它会工作,但是我只会把方法安排在一个月的最后几天,比如27-31天。是的,我认为这会是一些优化,但是你说你想要每个月的最后一天。对不起,我把自己放错了…“不仅仅是最后几天”..我想每月安排一次,一天可以是一个月的任何一天..但问题只出现在最后几天…即2月29日..而且我的cron表达式对于单个任务是动态的。检查更新..谢谢,我不能使用quartz,因为它需要架构级重构..“他们会杀了我”..我会试试你的想法它似乎会奏效。。。