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

逃离我推掉我的手 2023-09-29 17:26 116阅读 0赞

文章目录

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

背景需求

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

87d77b2c11d54284514318da6429a21b.png

代码实现

枚举及常量

定义执行周期:

  1. /**
  2. * 执行周期枚举
  3. *
  4. * @author zhurunhua
  5. * @since 2022/10/24 11:30
  6. */
  7. public enum PeriodEnum {
  8. /**
  9. * 执行一次
  10. */
  11. ONCE,
  12. /**
  13. * 每天
  14. */
  15. DAILY,
  16. /**
  17. * 每周
  18. */
  19. WEEKLY,
  20. /**
  21. * 每月
  22. */
  23. MONTHLY
  24. }

定义星期中英文枚举

  1. /**
  2. * 星期枚举
  3. *
  4. * @author zhurunhua
  5. * @since 2022/10/24 11:30
  6. */
  7. @Getter
  8. public enum WeekEnum {
  9. /**
  10. * 周一
  11. */
  12. Monday("星期一", "Mon"),
  13. /**
  14. * 周二
  15. */
  16. Tuesday("星期二", "Tue"),
  17. /**
  18. * 周三
  19. */
  20. Wednesday("星期三", "Wed"),
  21. /**
  22. * 周四
  23. */
  24. Thursday("星期四", "Thu"),
  25. /**
  26. * 周五
  27. */
  28. Friday("星期五", "Fri"),
  29. /**
  30. * 周六
  31. */
  32. Saturday("星期六", "Sat"),
  33. /**
  34. * 周日
  35. */
  36. Sunday("星期日", "Sun"),
  37. ;
  38. private static final Map<String, WeekEnum> CODE_ROLE_MAP = new HashMap<>();
  39. private static final Map<String, WeekEnum> NAME_ROLE_MAP = new HashMap<>();
  40. static {
  41. for (WeekEnum type : WeekEnum.values()) {
  42. NAME_ROLE_MAP.put(type.name, type);
  43. CODE_ROLE_MAP.put(type.code, type);
  44. }
  45. }
  46. private final String name;
  47. private final String code;
  48. WeekEnum(final String name, final String code) {
  49. this.name = name;
  50. this.code = code;
  51. }
  52. /**
  53. * to WeekEnum by code.
  54. *
  55. * @param code code
  56. * @return WeekEnum
  57. */
  58. public static WeekEnum codeOf(final String code) {
  59. if (StringUtils.isBlank(code)) {
  60. return Sunday;
  61. }
  62. WeekEnum matchType = CODE_ROLE_MAP.get(code);
  63. return Objects.isNull(matchType) ? Sunday : matchType;
  64. }
  65. /**
  66. * to WeekEnum by name.
  67. *
  68. * @param name name
  69. * @return WeekEnum
  70. */
  71. public static WeekEnum nameOf(final String name) {
  72. if (Strings.isNullOrEmpty(name)) {
  73. return Sunday;
  74. }
  75. WeekEnum matchType = NAME_ROLE_MAP.get(name);
  76. return Objects.isNull(matchType) ? Sunday : matchType;
  77. }

cron表达式模板常量:

  1. /**
  2. * cron表达式模板
  3. *
  4. * @author zhurunhua
  5. * @since 2022/10/24 11:50
  6. */
  7. public interface CronPatternConstant {
  8. /**
  9. * 执行单次cron表达式模板
  10. * eg: 59 59 23 1 12 ? 2022 (2022-12-01 23:59:59执行一次)
  11. */
  12. String ONCE_CRON_PATTERN = "%s %s %s %s %s ? %s";
  13. /**
  14. * 每天执行cron表达式模板
  15. * eg: 59 59 23 * * ? (每日23:59:59执行)
  16. */
  17. String DAILY_CRON_PATTERN = "%s %s %s * * ?";
  18. /**
  19. * 每周执行cron表达式模板
  20. * eg: 59 59 23 ? * Fri (每周五23:59:59执行)
  21. */
  22. String WEEKLY_CRON_PATTERN = "%s %s %s ? * %s";
  23. /**
  24. * 每月执行cron表达式模板
  25. * eg: 59 59 23 8 * ? (每月8号23:59:59执行)
  26. */
  27. String MONTHLY_CRON_PATTERN = "%s %s %s %s * ?";
  28. }

工具类

  1. /**
  2. * Cron表达式工具类
  3. *
  4. * @author zhurunhua
  5. * @since 2022/10/24 11:46
  6. */
  7. @Slf4j
  8. public enum GenerateCronUtil {
  9. /**
  10. * 单例
  11. */
  12. INSTANCE;
  13. private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  14. private final SimpleDateFormat weekFormat = new SimpleDateFormat("E");
  15. /**
  16. * 根据执行周期和初次执行时间,生成cron表达式
  17. *
  18. * @param period 执行周期
  19. * @param beginTime 初次执行时间
  20. * @return cron表达式
  21. */
  22. public String generateCronByPeriodAndTime(PeriodEnum period, String beginTime) {
  23. Date parsedDate;
  24. try {
  25. parsedDate = dateFormat.parse(beginTime);
  26. } catch (ParseException e) {
  27. log.error("parse time error. [time]: {}", beginTime);
  28. return "";
  29. }
  30. String[] dateAndTime = beginTime.split(" ");
  31. String date = dateAndTime[0];
  32. String time = dateAndTime[1];
  33. String[] splitDate = date.split("-");
  34. String year = splitDate[0];
  35. String month = splitDate[1];
  36. String day = splitDate[2];
  37. String[] splitTime = time.split(":");
  38. String hour = splitTime[0];
  39. String minute = splitTime[1];
  40. String second = splitTime[2];
  41. String cron = "";
  42. switch (period) {
  43. case ONCE:
  44. cron = String.format(CronPatternConstant.ONCE_CRON_PATTERN, second, minute, hour, day, month, year);
  45. break;
  46. case DAILY:
  47. cron = String.format(CronPatternConstant.DAILY_CRON_PATTERN, second, minute, hour);
  48. break;
  49. case WEEKLY:
  50. String week = weekFormat.format(parsedDate);
  51. String weekCode = WeekEnum.nameOf(week).getCode();
  52. cron = String.format(CronPatternConstant.WEEKLY_CRON_PATTERN, second, minute, hour, weekCode);
  53. break;
  54. case MONTHLY:
  55. cron = String.format(CronPatternConstant.MONTHLY_CRON_PATTERN, second, minute, hour, day);
  56. break;
  57. default:
  58. break;
  59. }
  60. return cron;
  61. }
  62. }

测试

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

输出:

  1. 单次执行cron00 00 12 01 12 ? 2022
  2. 每天执行cron00 00 12 * * ?
  3. 每周执行cron00 00 12 ? * Thu
  4. 每月执行cron00 00 12 01 * ?

发表评论

表情:
评论列表 (有 0 条评论,116人围观)

还没有评论,来说两句吧...

相关阅读