Java 根据Cron表达式获取近几次任务执行时间

50 篇文章 2 订阅

这篇博客将介绍Java 如何根据Cron表达式获取近几次任务执行时间。实际上使用 quartzCronSequenceGenerator 以及TriggerUtils.computeFireTimes 俩种方法进行时间获取;

1. 效果图

在这里插入图片描述

2. 源码

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.3.0</version>
</dependency>
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.quartz.CronExpression;
import org.quartz.TriggerUtils;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.springframework.scheduling.support.CronSequenceGenerator;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

/*****************************
 * Class Name: CronUtil
 * Description: <获取Cron表达式最近几次执行的时间>
 * @Author: Seminar
 * @create: 2022/11/02
 * @since: 1.0.0
 ***************************/
@Slf4j
public class CronUtil {

    public void getTime() {
        String cronExpress = "0 */30 * * * ?";//此处为cron表达式
        cronExpress = "0 0/30 * * * ?";
        try {
            CronExpression cronExpression = new CronExpression(cronExpress);//导包import org.quartz.CronExpression;
            Date date = cronExpression.getTimeAfter(new Date());
            //将date转换为指定日期格式字符串
            SimpleDateFormat dataFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String dateString = dataFormat.format(date);
            //dateString为转换后的日期格式
            log.info("{} {}", cronExpress, dateString);
        } catch (Exception e) {
            log.error("cron获取下次执行时间异常" + e);
        }
    }

    /**
     * 列出近cronCount次的执行时间
     *
     * @param cronExpression cron表达式
     * @param cronCount      cron时间次数
     * @param maxCronCount   最大cron时间次数
     * @return
     */
    public static List<String> listCronRunTime(String cronExpression, Integer cronCount, Integer maxCronCount) {
        if (StringUtils.isBlank(cronExpression)) {
            throw new RuntimeException("Cron 表达式不能为空!");
        }
        if (!CronSequenceGenerator.isValidExpression(cronExpression)) {
            throw new RuntimeException("Cron格式不正确,Cron: " + cronExpression);
        }
        if (cronCount < 1) {
            cronCount = 1;
        }
        if (maxCronCount < 1) {
            maxCronCount = 100;
        }
        if (cronCount > maxCronCount) {
            cronCount = maxCronCount;
        }
        CronSequenceGenerator cronSequenceGenerator = new CronSequenceGenerator(cronExpression);
        List<String> cronTimeList = new ArrayList<>();
        Date nextTimePoint = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (int i = 0; i < cronCount; i++) {
            nextTimePoint = cronSequenceGenerator.next(nextTimePoint);
            cronTimeList.add(sdf.format(nextTimePoint));
        }
        return cronTimeList;
    }

    /**
     * 列出近numTimes次的执行时间
     *
     * @param cronExpression cron表达式
     * @param numTimes       下几次运行时间
     * @return
     */
    public static List<String> getNextExecTime(String cronExpression, Integer numTimes) {
        List<String> list = new ArrayList<>();
        CronTriggerImpl cronTriggerImpl = new CronTriggerImpl();
        try {
            cronTriggerImpl.setCronExpression(cronExpression);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        // 这个是重点,一行代码搞定
        List<Date> dates = TriggerUtils.computeFireTimes(cronTriggerImpl, null, numTimes);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (Date date : dates) {
            list.add(dateFormat.format(date));
        }
        return list;
    }

    /**
     * Java8 通过foreach 遍历List,同时输出下标
     * 利用BiConsumer实现foreach循环支持index
     *
     * @param biConsumer
     * @param <T>
     * @return
     */
    public static <T> Consumer<T> forEachWithIndex(BiConsumer<T, Integer> biConsumer) {
        /*这里说明一下,我们每次传入forEach都是一个重新实例化的Consumer对象,在lambada表达式中我们无法对int进行++操作,
        我们模拟AtomicInteger对象,写个getAndIncrement方法,不能直接使用AtomicInteger哦*/
        class IncrementInt {
            int i = 0;

            public int getAndIncrement() {
                return i++;
            }
        }
        IncrementInt incrementInt = new IncrementInt();
        return t -> biConsumer.accept(t, incrementInt.getAndIncrement());
    }

    public static void main(String[] args) {
        CronUtil cronUtil = new CronUtil();
        cronUtil.getTime();


        String cron = "0 0/30 * * * ?"; // 0 0/30 * * * ? 每隔30分钟执行一次 同 0 */30 * * * ?
        cron = "0 0/5 14 * * ?"; // 0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发
        log.info("cron: {}", cron);
        List<String> timeList = listCronRunTime(cron, 10, 100);
        timeList.stream().forEach(forEachWithIndex((item, index) -> {
            log.info("{} {}", index + 1, item);
        }));

        List<String> time2List = getNextExecTime(cron, 10);
        time2List.stream().forEach(x -> {
            log.info("---- {}", x);
        });
    }
}

参考

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序媛一枚~

您的鼓励是我创作的最大动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值