<dependency>
    <groupId>com.cronutils</groupId>
    <artifactId>cron-utils</artifactId>
    <version>9.2.0</version>
</dependency>

计划执行定义类

 package com.example.demo.domain;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;

public class PlanExecuteDefBO {

    private static final long serialVersionUID = 4334316357655011464L;

    /**
     * 周期类型 minute:分钟 hour: 小时; day: 天; week: 周; month: 月; quarter: 季; year: 年
     */
    private String cycleType;

    /**
     * cron表达式
     */
    private String cron;

    /**
     * 定时任务id
     */
    private String jobId;

    /**
     * 开始时间
     */
    private LocalDate startTime;

    /**
     * 结束时间
     */
    private LocalDate endTime;

    /**
     * 周期内次数
     */
    private Integer numberOfCycles;

    /**
     * 指定一周哪几天
     */
    private List<Integer> weekDays;

    /**
     * 指定一个月哪几天
     */
    private List<Integer> monthDays;

    /**
     * 一周的星期几
     */
    private Integer dayOfWeek;

    /**
     * 第几周
     */
    private Integer week;

    /**
     * 重复规则
     */
    private String repeatRule;

    /**
     * 执行时间
     */
    private LocalTime executionTime;

    public String getCycleType() {
        return cycleType;
    }

    public void setCycleType(String cycleType) {
        this.cycleType = cycleType;
    }

    public void setStartTime(LocalDate startTime) {
        this.startTime = startTime;
    }

    public void setEndTime(LocalDate endTime) {
        this.endTime = endTime;
    }

    public String getCron() {
        return cron;
    }

    public void setCron(String cron) {
        this.cron = cron;
    }

    public String getJobId() {
        return jobId;
    }

    public void setJobId(String jobId) {
        this.jobId = jobId;
    }

    public Integer getNumberOfCycles() {
        return numberOfCycles;
    }

    public void setNumberOfCycles(Integer numberOfCycles) {
        this.numberOfCycles = numberOfCycles;
    }

    public LocalDate getStartTime() {
        return startTime;
    }

    public LocalDate getEndTime() {
        return endTime;
    }

    public List<Integer> getWeekDays() {
        return weekDays;
    }

    public void setWeekDays(List<Integer> weekDays) {
        this.weekDays = weekDays;
    }

    public List<Integer> getMonthDays() {
        return monthDays;
    }

    public void setMonthDays(List<Integer> monthDays) {
        this.monthDays = monthDays;
    }

    public Integer getDayOfWeek() {
        return dayOfWeek;
    }

    public void setDayOfWeek(Integer dayOfWeek) {
        this.dayOfWeek = dayOfWeek;
    }

    public Integer getWeek() {
        return week;
    }

    public void setWeek(Integer week) {
        this.week = week;
    }

    public String getRepeatRule() {
        return repeatRule;
    }

    public void setRepeatRule(String repeatRule) {
        this.repeatRule = repeatRule;
    }

    public LocalTime getExecutionTime() {
        return executionTime;
    }

    public void setExecutionTime(LocalTime executionTime) {
        this.executionTime = executionTime;
    }
}

枚举类

计划周期类型映射

package com.example.demo.utils;

public enum PlanCycleTypeEnum {
    MINUTE("minute", "分钟"),

    HOUR("hour", "小时"),

    DAY("day", "日"),

    WEEK("week", "周"),

    MONTH("month", "月"),

    QUARTER("quarter", "季度"),

    YEAR("year", "年");


    /**
     * 周期类型
     */
    private String cycleType;

    /**
     * 描述
     */
    private String description;

    PlanCycleTypeEnum(String cycleType, String description) {
        this.cycleType = cycleType;
        this.description = description;
    }

    public String getCycleType() {
        return cycleType;
    }

    public String getDescription() {
        return description;
    }
}

重复规则映射

选择每月周期执行可选择每月某几天执行或每月的第几周的星期几执行

package com.example.demo.utils;

/**
 * @author cmf
 * @date 2023/11/17
 */
public enum RepeatRuleEnum {
    WEEK("week", "周"),

    DATE("date", "日期");

    private String value;

    private String description;

    RepeatRuleEnum(String type, String description) {
        this.value = type;
        this.description = description;
    }

    public String getType() {
        return value;
    }

    public void setType(String type) {
        this.value = type;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

星期映射

package com.example.demo.utils;

public enum WeekEnum {
    SUNDAY(1, "星期天"),

    MONDAY(2, "星期一"),

    TUESDAY(3, "星期二"),

    WEDNESDAY(4, "星期三"),

    THURSDAY(5, "星期四"),

    FRIDAY(6, "星期五"),

    SATURDAY(7, "星期六");

    private Integer value;

    private String description;

    WeekEnum(Integer value, String description) {
        this.value = value;
        this.description = description;
    }

    public Integer getValue() {
        return value;
    }

    public void setValue(Integer value) {
        this.value = value;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

CronUtils

package com.example.demo.utils;

import com.cronutils.builder.CronBuilder;
import com.cronutils.model.CronType;
import com.cronutils.model.definition.CronDefinitionBuilder;
import com.cronutils.model.field.expression.FieldExpression;
import com.cronutils.model.field.expression.On;
import com.cronutils.model.field.value.SpecialChar;
import com.example.demo.domain.PlanExecuteDefBO;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import static com.cronutils.model.field.expression.FieldExpressionFactory.*;

public class CronUntils {
    /**
     * 星期
     */
    private static final List<Integer> WEEKS = Arrays.asList(WeekEnum.SUNDAY.getValue(),
            WeekEnum.MONDAY.getValue(),
            WeekEnum.THURSDAY.getValue(),
            WeekEnum.WEDNESDAY.getValue(),
            WeekEnum.THURSDAY.getValue(),
            WeekEnum.FRIDAY.getValue(),
            WeekEnum.SATURDAY.getValue());

    private static CronBuilder
            cronBuilder;

    static {
        cronBuilder = CronBuilder.cron(CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ));
    }

    public static String createCron(PlanExecuteDefBO planExecuteDefBO) {
        LocalTime executionTime = planExecuteDefBO.getExecutionTime();
        LocalDate startTime = planExecuteDefBO.getStartTime();
        String cycleType = planExecuteDefBO.getCycleType();
        int minute = planExecuteDefBO.getExecutionTime().getMinute();
        int hour = executionTime.getHour();
        int day = startTime.getDayOfMonth();
        int month = startTime.getMonth().getValue();
        cronBuilder = cronBuilder.withSecond(on(executionTime.getSecond()));
        // 每分钟一次
        if (Objects.equals(PlanCycleTypeEnum.MINUTE.getCycleType(), cycleType)) {
            return cronBuilder.withDoW(questionMark())
                    .withMonth(always())
                    .withDoM(always())
                    .withHour(always())
                    .withMinute(always()).instance().asString();
        }

        // 每小时一次
        if (Objects.equals(PlanCycleTypeEnum.HOUR.getCycleType(), cycleType)) {
            return cronBuilder.withDoW(
                    questionMark())
                    .withMonth(always())
                    .withDoM(always())
                    .withHour(always())
                    .withMinute(on(executionTime.getMinute()))
                    .instance()
                    .asString();
        }

        // 每天一次
        if (Objects.equals(PlanCycleTypeEnum.DAY.getCycleType(), cycleType)) {
            return cronBuilder.withDoW(
                    questionMark())
                    .withMonth(always())
                    .withDoM(always())
                    .withHour(on(hour))
                    .withMinute(on(minute))
                    .instance().asString();
        }

        // 每周一次
        if (Objects.equals(PlanCycleTypeEnum.WEEK.getCycleType(), cycleType)) {
            List<FieldExpression> weekDays = new ArrayList<>();
            planExecuteDefBO.getWeekDays().
                    forEach(e -> weekDays.add(on(e)));
            return cronBuilder.withDoW(
                    and(weekDays))
                    .withMonth(always())
                    .withDoM(questionMark())
                    .withHour(on(hour))
                    .withMinute(on(minute))
                    .instance().asString();
        }

        // 每月一次
        if (Objects.equals(PlanCycleTypeEnum.MONTH.getCycleType(), cycleType)) {
            List<FieldExpression> monthDays = new ArrayList<>();
            planExecuteDefBO.getMonthDays().

                    forEach(e -> monthDays.add(on(e)));
            if (Objects.equals(RepeatRuleEnum.DATE.getType(), planExecuteDefBO.getRepeatRule())) {
                return cronBuilder.withDoW(questionMark())
                        .withMonth(always())
                        .withDoM(and(monthDays))
                        .withHour(on(hour))
                        .withMinute(on(minute))
                        .instance().asString();
            }
            if (Objects.equals(RepeatRuleEnum.WEEK.getType(), planExecuteDefBO.getRepeatRule())) {
                return cronBuilder.withDoW(on(WEEKS.get(planExecuteDefBO.getDayOfWeek()), SpecialChar.HASH, planExecuteDefBO.getWeek()))
                        .withMonth(always())
                        .withDoM(questionMark())
                        .withHour(on(hour))
                        .withMinute(on(minute))
                        .instance().asString();
            }
        }

        // 每季度一次
        if (Objects.equals(PlanCycleTypeEnum.QUARTER.getCycleType(), cycleType)) {
            List<FieldExpression> flist = new ArrayList<>();
            On quarter1 = on(1);
            On quarter2 = on(4);
            On quarter3 = on(7);
            On quarter4 = on(10);
            flist.add(quarter1);
            flist.add(quarter2);
            flist.add(quarter3);
            flist.add(quarter4);
            return cronBuilder.withDoW(
                    questionMark())
                    .withMonth(and(flist))
                    .withDoM(on(day))
                    .withHour(on(hour))
                    .withMinute(on(minute))
                    .instance().asString();
        }

        // 每年一次
        if (Objects.equals(PlanCycleTypeEnum.YEAR.getCycleType(), cycleType)) {
            List<FieldExpression> flist = new ArrayList<>();
            On on = on(day);
            flist.add(on);
            return cronBuilder.withYear(
                    always())
                    .withDoW(questionMark())
                    .withMonth(on(month))
                    .withDoM(on(day))
                    .withHour(on(hour))
                    .withMinute(on(minute))
                    .instance().asString();
        }
        // 按秒执行
        return cronBuilder.withYear(always())
                .withDoW(questionMark())
                .withMonth(always())
                .withDoM(always())
                .withHour(always())
                .withMinute(always()).instance().asString();
    }
}

测试类

package com.example.demo.utils;

import com.cronutils.descriptor.CronDescriptor;
import com.cronutils.model.CronType;
import com.cronutils.model.definition.CronDefinition;
import com.cronutils.model.definition.CronDefinitionBuilder;
import com.cronutils.parser.CronParser;
import com.example.demo.domain.PlanExecuteDefBO;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Arrays;
import java.util.Locale;

public class CronDemo {
    public static void main(String[] args) {
        CronDefinition cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ);
        CronParser parser = new CronParser(cronDefinition);
        CronDescriptor descriptor = CronDescriptor.instance(Locale.UK);
        LocalDate startTime = LocalDate.of(2022, 9, 1);
        LocalTime executeTime = LocalTime.of(9, 0, 0);
        PlanExecuteDefBO planExecuteDefBO = new PlanExecuteDefBO();
        planExecuteDefBO.setStartTime(startTime);
        planExecuteDefBO.setExecutionTime(executeTime);
        planExecuteDefBO.setCycleType("minute");
        // 每分钟执行一次
        String minute = CronUntils.createCron(planExecuteDefBO);
        System.out.println("每分钟:" + minute + ":" + descriptor.describe(parser.parse(minute)));

        // 每小时执行一次
        planExecuteDefBO.setCycleType("hour");
        String hour = CronUntils.createCron(planExecuteDefBO);
        System.out.println("每小时:" + hour + ":" + descriptor.describe(parser.parse(hour)));

        // 每天执行一次
        planExecuteDefBO.setCycleType("day");
        String day = CronUntils.createCron(planExecuteDefBO);
        System.out.println("每天:" + day + ":" + descriptor.describe(parser.parse(day)));

        // 每周执行一次
        planExecuteDefBO.setCycleType("week");
        planExecuteDefBO.setWeekDays(Arrays.asList(1, 3));
        String week = CronUntils.createCron(planExecuteDefBO);
        System.out.println("每周:" + week + ":" + descriptor.describe(parser.parse(week)));

        // 每月执行一次
        planExecuteDefBO.setCycleType("month");
        planExecuteDefBO.setMonthDays(Arrays.asList(1, 11, 25));
        //planExecuteDefBO.setRepeatRule("date"); // 指定月内某几天执行
        planExecuteDefBO.setRepeatRule("week"); // 可选每月第几周的星期几执行
        planExecuteDefBO.setDayOfWeek(1);
        planExecuteDefBO.setWeek(1);
        String month = CronUntils.createCron(planExecuteDefBO);
        System.out.println("每月:" + month + ":" + descriptor.describe(parser.parse(month)));

        // 每季度执行一次
        planExecuteDefBO.setCycleType("quarter");
        String quarter = CronUntils.createCron(planExecuteDefBO);
        System.out.println("每季度:" + quarter + ":" + descriptor.describe(parser.parse(quarter)));

        // 每年执行一次
        planExecuteDefBO.setCycleType("year");
        String year = CronUntils.createCron(planExecuteDefBO);
        System.out.println("每年:" + year + ":" + descriptor.describe(parser.parse(year)));


    }
}

转自:https://blog.csdn.net/qq_34117294/article/details/129490210