如何计算指定时间的下一次执行时间

本文介绍了一个任务调度解析器的设计与实现,包括Cron表达式、固定延迟和固定频率三种任务调度方式。通过继承抽象基类TimeParser,实现了CronParser、FixedDelayParser和FixedRateParser三个子类,分别用于解析不同的任务调度策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.0</version>
        </dependency>

        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.10.2</version>
        </dependency>
package timer;

import org.joda.time.DateTime;
import org.quartz.Calendar;

public abstract class TimeParser {

    protected String timeExpression;

    protected Calendar calendar;

    public TimeParser(String timeExpression) {
        this.timeExpression = timeExpression;
    }

    public TimeParser(String timeExpression, Calendar calendar) {
        this.timeExpression = timeExpression;
        this.calendar = calendar;
    }

    public String getTimeExpression() {
        return timeExpression;
    }

    public void setTimeExpression(String timeExpression) {
        this.timeExpression = timeExpression;
    }

    public Calendar getCalendar() {
        return calendar;
    }

    public void setCalendar(Calendar calendar) {
        this.calendar = calendar;
    }

    public abstract DateTime getTimeAfter(DateTime dt);

    public abstract DateTime getTimeBefore(DateTime dt);

}
package timer;

import org.joda.time.DateTime;
import org.quartz.Calendar;
import org.quartz.CronExpression;

import java.text.ParseException;
import java.util.Date;
import java.util.TimeZone;

public class CronParser extends TimeParser {


    private final CronExpression cronExpression;

    private String timezone;

    public CronParser(String timeExpression) throws ParseException {
        super(timeExpression);
        this.cronExpression=new CronExpression(timeExpression);
    }

    public CronParser(String timeExpression, Calendar calendar) throws ParseException {
        super(timeExpression,calendar);
        this.cronExpression=new CronExpression(timeExpression);
    }

    @Override
    public DateTime getTimeAfter(DateTime dt) {
        Date nextFireTime=cronExpression.getTimeAfter(dt.toDate());
        while (nextFireTime!=null&&calendar!=null&&!calendar.isTimeIncluded(nextFireTime.getTime())){
            nextFireTime=cronExpression.getTimeAfter(nextFireTime);
        }
        if(nextFireTime!=null){
            return new DateTime(nextFireTime);
        }
        return null;
    }

    @Override
    public DateTime getTimeBefore(DateTime dt) {

        Date lastFireTime=cronExpression.getTimeBefore(dt.toDate());
        while (lastFireTime!=null&&calendar!=null&&!calendar.isTimeIncluded(lastFireTime.getTime())){
            lastFireTime=cronExpression.getTimeBefore(lastFireTime);
        }
        return new DateTime(lastFireTime);
    }

    public String  getTimezone(){
        return timezone;
    }

    public void setTimezone(String timezone){
        this.timezone=timezone;
        if(timezone.equals("Asia/Beijing")){
            this.timezone="Asia/Shanghai";
        }
        cronExpression.setTimeZone(TimeZone.getTimeZone(this.timezone));
    }

    public static void main(String[] args) throws ParseException{
        CronParser cronParser=new CronParser("10 0 0,0,0 * * ?");
    }
}
package timer;

import org.joda.time.DateTime;

public class FixedDelayParser extends TimeParser {

    private final int delaySeconds;

    public FixedDelayParser(String timeExpression) {
        super(timeExpression);
        this.delaySeconds = Integer.valueOf(timeExpression);
    }

    @Override
    public DateTime getTimeAfter(DateTime dt) {

        DateTime nextFireTime=dt.plusSeconds(delaySeconds);
        while (nextFireTime!=null&&calendar!=null&&!calendar.isTimeIncluded(nextFireTime.getMillis())){
            nextFireTime=nextFireTime.plusSeconds(delaySeconds);
        }
        return nextFireTime;
    }

    @Override
    public DateTime getTimeBefore(DateTime dt) {
        DateTime lastFireTime=dt.minusSeconds(delaySeconds);
        while (lastFireTime!=null&&calendar!=null&&!calendar.isTimeIncluded(lastFireTime.getMillis())){
            lastFireTime=lastFireTime.minusSeconds(delaySeconds);
        }
        return lastFireTime;
    }
}
package timer;

import org.joda.time.DateTime;

public class FixedRateParser extends TimeParser {

    private final int rateSeconds;

    public FixedRateParser(String timeExpression) {
        super(timeExpression);
        this.rateSeconds = Integer.valueOf(timeExpression);
    }


    @Override
    public DateTime getTimeAfter(DateTime dt) {
        DateTime nextFireTime=dt.plusSeconds(rateSeconds);
        while (nextFireTime!=null&&calendar!=null&&!calendar.isTimeIncluded(nextFireTime.getMillis())){
            nextFireTime=nextFireTime.plusSeconds(rateSeconds);
        }
        return nextFireTime;
    }

    @Override
    public DateTime getTimeBefore(DateTime dt) {
        DateTime lastFireTime=dt.minusSeconds(rateSeconds);
        while (lastFireTime!=null&&calendar!=null&&!calendar.isTimeIncluded(lastFireTime.getMillis())){
            lastFireTime=lastFireTime.minusSeconds(rateSeconds);
        }
        return lastFireTime;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值