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

背景需求

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

代码实现

枚举及常量

定义执行周期:

/**
 * 执行周期枚举
 *
 * @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 * ?
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
好的,根据您的问题,我可以给出一个参考答案: Java中可以使用Quartz Cron表达式生成器来生成Cron表达式。下面是一个示例代码: ```java import org.quartz.CronExpression; public class CronExpressionGenerator { public static void main(String[] args) { // 根据秒生成cron表达式,这里以每分钟的第30秒为例 String cronExpression = generateCronExpression("30 * * * * ?"); System.out.println(cronExpression); // 输出:0 0/1 * 1/1 * ? * } /** * 根据给定时间表达式生成Cron表达式 * @param timeExpression 时间表达式,格式为 "ss mm HH dd MM ? yyyy" * @return Cron表达式 */ public static String generateCronExpression(String timeExpression) { // 将时间表达式转换CronExpression对象 CronExpression cronExpression = null; try { cronExpression = new CronExpression(timeExpression); } catch (Exception e) { e.printStackTrace(); } // 根据CronExpression对象生成Cron表达式 return cronExpression == null ? null : cronExpression.getCronExpression(); } } ``` 代码中使用了Quartz框架中的CronExpression类来将时间表达式转换Cron表达式。需要注意的是,时间表达式的格式为 "ss mm HH dd MM ? yyyy",其中ss表示秒,mm表示分,HH表示小时,dd表示天,MM表示月,yyyy表示年。而Cron表达式的格式为 "秒 分 时 日 月 周年",其中周年可以省略。 以上代码只是一个简单示例,您可以根据自己的需求进行修改和扩展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值