【Java】给定执行周期和首次执行时间,生成Cron表达式工具类

文章目录

  • 背景需求
  • 代码实现
    • 枚举及常量
    • 工具类
    • 测试

背景需求

页面通过配置执行周期和初次执行时间,后台根据这两个参数,生成对应的Cron表达式,定期生成执行任务的Task,当然,这里也可以直接使用Cron表达式插件,但是对使用者有一定的理解成本。

【Java】给定执行周期和首次执行时间,生成Cron表达式工具类_第1张图片

代码实现

枚举及常量

定义执行周期:

/**
 * 执行周期枚举
 *
 * @author zhurunhua
 * @since 2022/10/24 11:30
 */
public enum PeriodEnum {
    /**
     * 执行一次
     */
    ONCE,
    /**
     * 每天
     */
    DAILY,
    /**
     * 每周
     */
    WEEKLY,
    /**
     * 每月
     */
    MONTHLY
}

定义星期中英文枚举

/**
 * 星期枚举
 *
 * @author zhurunhua
 * @since 2022/10/24 11:30
 */
@Getter
public enum WeekEnum {

    /**
     * 周一
     */
    Monday("星期一", "Mon"),
    /**
     * 周二
     */
    Tuesday("星期二", "Tue"),
    /**
     * 周三
     */
    Wednesday("星期三", "Wed"),
    /**
     * 周四
     */
    Thursday("星期四", "Thu"),
    /**
     * 周五
     */
    Friday("星期五", "Fri"),
    /**
     * 周六
     */
    Saturday("星期六", "Sat"),
    /**
     * 周日
     */
    Sunday("星期日", "Sun"),
    ;

    private static final Map<String, WeekEnum> CODE_ROLE_MAP = new HashMap<>();

    private static final Map<String, WeekEnum> NAME_ROLE_MAP = new HashMap<>();

    static {
        for (WeekEnum type : WeekEnum.values()) {
            NAME_ROLE_MAP.put(type.name, type);
            CODE_ROLE_MAP.put(type.code, type);
        }
    }

    private final String name;

    private final String code;

    WeekEnum(final String name, final String code) {
        this.name = name;
        this.code = code;
    }

    /**
     * to WeekEnum by code.
     *
     * @param code code
     * @return WeekEnum
     */
    public static WeekEnum codeOf(final String code) {
        if (StringUtils.isBlank(code)) {
            return Sunday;
        }
        WeekEnum matchType = CODE_ROLE_MAP.get(code);
        return Objects.isNull(matchType) ? Sunday : matchType;
    }

    /**
     * to WeekEnum by name.
     *
     * @param name name
     * @return WeekEnum
     */
    public static WeekEnum nameOf(final String name) {
        if (Strings.isNullOrEmpty(name)) {
            return Sunday;
        }
        WeekEnum matchType = NAME_ROLE_MAP.get(name);
        return Objects.isNull(matchType) ? Sunday : matchType;
    }

cron表达式模板常量:

/**
 * cron表达式模板
 *
 * @author zhurunhua
 * @since 2022/10/24 11:50
 */
public interface CronPatternConstant {
    /**
     * 执行单次cron表达式模板
     * eg: 59 59 23 1 12 ? 2022 (2022-12-01 23:59:59执行一次)
     */
    String ONCE_CRON_PATTERN = "%s %s %s %s %s ? %s";
    /**
     * 每天执行cron表达式模板
     * eg: 59 59 23 * * ? (每日23:59:59执行)
     */
    String DAILY_CRON_PATTERN = "%s %s %s * * ?";
    /**
     * 每周执行cron表达式模板
     * eg: 59 59 23 ? * Fri (每周五23:59:59执行)
     */
    String WEEKLY_CRON_PATTERN = "%s %s %s ? * %s";
    /**
     * 每月执行cron表达式模板
     * eg: 59 59 23 8 * ? (每月8号23:59:59执行)
     */
    String MONTHLY_CRON_PATTERN = "%s %s %s %s * ?";
}

工具类

/**
 * Cron表达式工具类
 *
 * @author zhurunhua
 * @since 2022/10/24 11:46
 */
@Slf4j
public enum GenerateCronUtil {
    /**
     * 单例
     */
    INSTANCE;

    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private final SimpleDateFormat weekFormat = new SimpleDateFormat("E");

    /**
     * 根据执行周期和初次执行时间,生成cron表达式
     *
     * @param period    执行周期
     * @param beginTime 初次执行时间
     * @return cron表达式
     */
    public String generateCronByPeriodAndTime(PeriodEnum period, String beginTime) {
        Date parsedDate;
        try {
            parsedDate = dateFormat.parse(beginTime);
        } catch (ParseException e) {
            log.error("parse time error. [time]: {}", beginTime);
            return "";
        }
        String[] dateAndTime = beginTime.split(" ");
        String date = dateAndTime[0];
        String time = dateAndTime[1];
        String[] splitDate = date.split("-");
        String year = splitDate[0];
        String month = splitDate[1];
        String day = splitDate[2];
        String[] splitTime = time.split(":");
        String hour = splitTime[0];
        String minute = splitTime[1];
        String second = splitTime[2];
        String cron = "";
        switch (period) {
            case ONCE:
                cron = String.format(CronPatternConstant.ONCE_CRON_PATTERN, second, minute, hour, day, month, year);
                break;
            case DAILY:
                cron = String.format(CronPatternConstant.DAILY_CRON_PATTERN, second, minute, hour);
                break;
            case WEEKLY:
                String week = weekFormat.format(parsedDate);
                String weekCode = WeekEnum.nameOf(week).getCode();
                cron = String.format(CronPatternConstant.WEEKLY_CRON_PATTERN, second, minute, hour, weekCode);
                break;
            case MONTHLY:
                cron = String.format(CronPatternConstant.MONTHLY_CRON_PATTERN, second, minute, hour, day);
                break;
            default:
                break;
        }
        return cron;
    }
}

测试

public class Test {
    public static void main(String[] args) throws ParseException {
        String time = "2022-12-01 12:00:00";
        String onceCron = GenerateCronUtil.INSTANCE.generateCronByPeriodAndTime(PeriodEnum.ONCE, time);
        String dailyCron = GenerateCronUtil.INSTANCE.generateCronByPeriodAndTime(PeriodEnum.DAILY, time);
        String weeklyCron = GenerateCronUtil.INSTANCE.generateCronByPeriodAndTime(PeriodEnum.WEEKLY, time);
        String monthlyCron = GenerateCronUtil.INSTANCE.generateCronByPeriodAndTime(PeriodEnum.MONTHLY, time);
        System.out.println("单次执行cron:" + onceCron);
        System.out.println("每天执行cron:" + dailyCron);
        System.out.println("每周执行cron:" + weeklyCron);
        System.out.println("每月执行cron:" + monthlyCron);
    }
}

输出:

单次执行cron:00 00 12 01 12 ? 2022
每天执行cron:00 00 12 * * ?
每周执行cron:00 00 12 ? * Thu
每月执行cron:00 00 12 01 * ?

你可能感兴趣的:(Java,1024程序员节,Cron表达式,定时任务)