java时间转Cron表达式

1. 工具类

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Cron工具类
 * 注意:此工具类异常都不处理,没有进行参数校验,
 * 调用方自行处理异常
 */
@Slf4j
public class JobCronUtil {

    private static final String EMPTY = "";
    private static final String SPACE = " ";
    private static final String COMMA = ",";
    private static final String HORIZONTAL_LINE = "-";
    private static final String STAR = "*";
    private static final String QUESTION_MARK = "?";
    private static final String FORWARD_SLASH = "/";
    private static final String POUND = "#";

    private JobCronUtil() {
    }

    /**
     * Model转成cron表达式
     */
    public static String getCron(CronModel cronModel) {
        log.debug("获取cron表达式参数 cronModel => {}", cronModel);
        /*
         * 指定时间点
         */
        if (JobType.TIME.equals(cronModel.getJobType())) {
            return getTimeCron(cronModel);
        }

        // 每隔几天
        else if (JobType.DAY.equals(cronModel.getJobType())) {
            return getDayCron(cronModel);
        }

        // 每隔几周
        else if (JobType.WEEK.equals(cronModel.getJobType())) {
            return getWeekCron(cronModel);
        }

        // 每隔几月的哪几个日期的时间点
        else if (JobType.MONTH_DAY.equals(cronModel.getJobType())) {
            return getMonthDayCron(cronModel);
        }

        // 每隔几月的第几个周几时间点
        else if (JobType.MONTH_WEEK.equals(cronModel.getJobType())) {
            return getMonthWeekCron(cronModel);
        }

        // 每隔几年
        else if (JobType.YEAR.equals(cronModel.getJobType())) {
            return getYearCron(cronModel);
        }

        // 任务类型配置错误
        else {
            log.error("任务类型配置错误");
            return null;
        }
    }

    /**
     * 指定时间点cron
     * 秒 分 时 日 月 周 年
     * 0 15 10 05 08 ? 2023
     * 2023-08-05 10:15:00
     */
    private static String getTimeCron(CronModel cronModel) {
        return cronModel.getSecond() + SPACE +
                cronModel.getMinute() + SPACE +
                cronModel.getHour() + SPACE +
                cronModel.getDayOfMonths()[0] + SPACE +
                cronModel.getMonths()[0] + SPACE +
                QUESTION_MARK + SPACE +
                cronModel.getYear();
    }

    /**
     * 每隔几天时间点cron
     */
    private static String getDayCron(CronModel cronModel) {
        // 秒 分 时  日  月 周
        // 0 15 10 */2  * ?
        // 每隔2天的10:15:00秒执行
        return cronModel.getSecond() + SPACE +
                cronModel.getMinute() + SPACE +
                cronModel.getHour() + SPACE +
                STAR + handleBeApart(cronModel) + SPACE +
                STAR + SPACE +
                QUESTION_MARK;
    }

    /**
     * 每隔几周时间点cron
     * 周	是	    1-7 或 SUN-SAT	 , - * ? / L #
     * 秒 分 时 日 月 周
     * 0 15 10 ?  * 1,3/2
     * 每隔2天的10:15:00秒执行
     */
    private static String getWeekCron(CronModel cronModel) {
        return cronModel.getSecond() + SPACE +
                cronModel.getMinute() + SPACE +
                cronModel.getHour() + SPACE +
                QUESTION_MARK + SPACE +
                STAR + SPACE +
                arr2Str(cronModel.getDayOfWeeks()) + FORWARD_SLASH + cronModel.getBeApart();
    }

    /**
     * 每隔几月的哪几个日期的时间点
     */
    private static String getMonthDayCron(CronModel cronModel) {
        // 每隔几月的哪几个日期的时间点
        // 秒 分 时     日     月   周
        // 0 15 10  1,2,5,8  */2  ?
        // 每隔2个月的1,2,5,8号10:15:00秒执行
        return cronModel.getSecond() + SPACE +
                cronModel.getMinute() + SPACE +
                cronModel.getHour() + SPACE +
                arr2Str(cronModel.getDayOfMonths()) + SPACE +
                STAR + handleBeApart(cronModel) + SPACE +
                QUESTION_MARK;
    }

    /**
     * 每隔几月的哪几个日期的时间点
     */
    private static String getMonthWeekCron(CronModel cronModel) {
        // 每隔几月的第几个周几时间点
        // 秒 分 时  日  月   周
        // 0 15 10  ?  */2  1#3
        // 每隔2个月的第三个周日10:15:00秒执行
        return cronModel.getSecond() + SPACE +
                cronModel.getMinute() + SPACE +
                cronModel.getHour() + SPACE +
                QUESTION_MARK + SPACE +
                STAR + handleBeApart(cronModel) + SPACE +
                cronModel.getDayOfWeek() + POUND + cronModel.getWeekOfMonth();
    }

    /**
     * 每隔几年的时间点
     */
    private static String getYearCron(CronModel cronModel) {
        // 每隔几年的时间点
        // 秒 分 时  日  月 周 年
        // 0 15 10  10  1  ? */2
        // 每隔2个月的第三个周日10:15:00秒执行
        return cronModel.getSecond() + SPACE +
                cronModel.getMinute() + SPACE +
                cronModel.getHour() + SPACE +
                arr2Str(cronModel.getDayOfMonths()) + SPACE +
                arr2Str(cronModel.getMonths()) + SPACE +
                QUESTION_MARK + SPACE +
                STAR + handleBeApart(cronModel);
    }


    private static String arr2Str(Integer[] arr) {
        if (checkNumberContinuous(arr)) {
            int min = Arrays.stream(arr).min(Integer::compareTo).orElse(0);
            int max = Arrays.stream(arr).max(Integer::compareTo).orElse(0);
            return min + HORIZONTAL_LINE + max;
        }
        StringBuilder sb = new StringBuilder();
        for (Integer num : arr) {
            sb.append(num).append(COMMA);
        }
        return sb.substring(0, sb.length() - 1);
    }

    /**
     * 检查数组是否连续的
     */
    private static boolean checkNumberContinuous(Integer[] arr) {
        List<Integer> list = Arrays.stream(arr).sorted().collect(Collectors.toList());
        int min = list.get(0);
        for (Integer value : list) {
            if (min != value) {
                return false;
            }
            min += 1;
        }
        return true;
    }

    private static String handleBeApart(CronModel cronModel) {
        return cronModel.getBeApart() == 1 ? EMPTY : (FORWARD_SLASH + cronModel.getBeApart());
    }

    /**
     * Cron类别
     */
    @AllArgsConstructor
    public enum JobType {

        /**
         * 固定时间
         */
        TIME(0, "固定时间"),

        /**
         * 每隔几天
         */
        DAY(1, "天"),

        /**
         * 每隔几周
         */
        WEEK(2, "周"),

        /**
         * 每隔几月的哪几个日期的时间点
         */
        MONTH_DAY(3, "月按日期"),

        /**
         * 每隔几月的第几个周几时间点
         */
        MONTH_WEEK(4, "月按星期"),

        /**
         * 每隔几年
         */
        YEAR(5, "年");

        @Getter
        private final Integer value;
        @Getter
        private final String name;

    }

    /**
     * Cron表达式对象
     * [秒] [分] [时] [日] [月] [周] [年]
     * 域	是否必填	值以及范围	     通配符
     * 秒	是	    0-59	         , - * /
     * 分	是	    0-59	         , - * /
     * 时	是	    0-23	         , - * /
     * 日	是	    1-31	         , - * ? / L W
     * 月	是	    1-12 或 JAN-DEC	 , - * /
     * 周	是	    1-7 或 SUN-SAT	 , - * ? / L #
     * 年	否	    1970-2099	     , - * /
     * <p>
     * # 表示每月的第几个周几,只能作用于 “周” 上。例如 ”2#3” 表示第三个周一。
     */
    @Data
    public static class CronModel {

        /**
         * 类型
         */
        JobType jobType;

        /**
         * 间隔
         */
        Integer beApart;

        /**
         * 秒
         */
        Integer second;

        /**
         * 分
         */
        Integer minute;

        /**
         * 时
         */
        Integer hour;

        /**
         * 日
         */
        Integer[] dayOfMonths;

        /**
         * 月
         */
        Integer[] months;

        /**
         * 周
         */
        Integer[] dayOfWeeks;

        /**
         * 第几个
         */
        Integer weekOfMonth;

        /**
         * 周几
         */
        Integer dayOfWeek;

        /**
         * 年
         */
        Integer year;
    }

}

2. 使用方式

可以自己通过构造CronModel来生成想要的cron

		JobCronUtil.CronModel cronModel = new JobCronUtil.CronModel();
        // 定时任务类别
        cronModel.setJobType(JobCronUtil.JobType.TIME);
        // 间隔
        cronModel.setBeApart(1);

        // 时间
        LocalDateTime dateTime = LocalDateTime.now();

        // 秒
        cronModel.setSecond(dateTime.getSecond());
        // 分
        cronModel.setMinute(dateTime.getMinute());
        // 时
        cronModel.setHour(dateTime.getHour());

        // 日
        cronModel.setDayOfMonths(new Integer[]{dateTime.getDayOfMonth()});
        // 月
        cronModel.setMonths(new Integer[]{dateTime.getMonthValue()});

        // 年
        cronModel.setYear(dateTime.getYear());

        String cron = JobCronUtil.getCron(cronModel);
您可以使用一个名为"CronToExpression"的Java库将时间换为cron表达式。这个库支持所有cron表达式的特殊字符,包括 * / - ? LW #。您可以通过传入日期来获取相应的cron表达式。下面是一个示例代码: ```java import java.util.Date; public class Main { public static void main(String[] args) { Date date = new Date(); String cron = CronToExpression.getCron(date); System.out.println("当前时间 " + date.toString() + " 的表达式为 " + cron); } } ``` 这个示例将当前时间换为cron表达式。您可以根据您的需求更改日期参数来换不同的时间。<span class="em">1</span><span class="em">2</span> #### 引用[.reference_title] - *1* [cron-parser:Cron表达式Java解析器](https://download.csdn.net/download/weixin_42131628/18342207)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [Java根据指定时间生成cron表达式](https://blog.csdn.net/qq_43102730/article/details/125289153)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值