Cron表达式中周和数字是不对应的
周一:2;周二:3;周三:4;周四:5;周五:6;周六:7;周日:1

pom文件必须依赖

     <dependency><groupId>com.cronutils</groupId><artifactId>cron-utils</artifactId><version>9.1.1</version></dependency><dependency><groupId>com.google.code.google-collections</groupId><artifactId>google-collect</artifactId><version>snapshot-20080530</version></dependency>

创建CronUtils工具类

package com.example.demo.utils;import com.cronutils.model.CronType;
import com.cronutils.model.definition.CronDefinition;
import com.cronutils.model.definition.CronDefinitionBuilder;
import com.cronutils.parser.CronParser;
import com.google.common.collect.Lists;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;/*** ClassName : CronUtils* Description : Cron表达式工具类* Author : x x x* Date : 2021/6/3 3:10 下午*/
@Component
public class CronUtils {private static final Logger LOGGER = LoggerFactory.getLogger(CronUtils.class);private static final String QUESTION = "?";private static final String ASTERISK = "*";private static final String COMMA = ",";/*** 替换 分钟、小时、日期、星期*/private static final String ORIGINAL_CRON = "0 %s %s %s * %s";/*** 检查cron表达式的合法性*/public boolean checkValid(String cron) {try {CronDefinition cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(CronType.SPRING);CronParser parser = new CronParser(cronDefinition);parser.parse(cron);} catch (IllegalArgumentException e) {LOGGER.error(String.format("cron=%s not valid", cron));return false;}return true;}public String buildCron(List<Integer> minutes, List<Integer> hours, List<Integer> weekdays) {String minute;if (minutes.equals(this.getInitMinutes())) {minute = ASTERISK;} else {minute = StringUtils.join(minutes, COMMA);}String hour;if (hours.equals(this.getInitHours())) {hour = ASTERISK;} else {hour = StringUtils.join(hours, COMMA);}String weekday;if (weekdays.equals(this.getInitWeekdays())) {weekday = QUESTION;} else {weekday = StringUtils.join(weekdays, COMMA);}// 重点:星期和日字段冲突,判断周日的前端输入if (weekday.equals(QUESTION)) {return String.format(ORIGINAL_CRON, minute, hour, ASTERISK, weekday);} else {return String.format(ORIGINAL_CRON, minute, hour, QUESTION, weekday);}}/*** 解析cron*/public CustomCronField parseCon(String cron) {if (!this.checkValid(cron)) {return null;}List<String> result = Arrays.asList(cron.trim().split(" "));CustomCronField field = new CustomCronField();if (result.get(1).contains(COMMA)) {field.setMinutes(Arrays.stream(result.get(1).split(COMMA)).map(Integer::parseInt).collect(Collectors.toList()));} else if (result.get(1).equals(ASTERISK)) {field.setMinutes(this.getInitMinutes());} else {field.setMinutes(Lists.newArrayList(Integer.parseInt(result.get(1))));}if (result.get(2).contains(COMMA)) {field.setHours(Arrays.stream(result.get(2).split(COMMA)).map(Integer::parseInt).collect(Collectors.toList()));} else if (result.get(2).equals(ASTERISK)) {field.setHours(this.getInitHours());} else {field.setHours(Lists.newArrayList(Integer.parseInt(result.get(2))));}if (result.get(5).contains(COMMA)) {field.setWeekdays(Arrays.stream(result.get(5).split(COMMA)).map(Integer::parseInt).collect(Collectors.toList()));} else if (result.get(5).equals(QUESTION)) {field.setWeekdays(this.getInitWeekdays());} else {field.setWeekdays(Lists.newArrayList(Integer.parseInt(result.get(5))));}return field;}/***  将Cron表达式解析为中文*/public String translateToChinese(String cronExp) {if (cronExp == null || cronExp.length() < 1) {return "cron表达式为空";}String[] tmpCorns = cronExp.split(" ");StringBuffer sBuffer = new StringBuffer();if (tmpCorns.length == 6) {//解析月if (!tmpCorns[4].equals("*") && !tmpCorns[4].equals("?")) {if (tmpCorns[4].contains("/")) {sBuffer.append("从").append(tmpCorns[4].split("/")[0]).append("号开始").append(",每").append(tmpCorns[4].split("/")[1]).append("月");} else {sBuffer.append("每年").append(tmpCorns[4]).append("月");}}//解析周if (!tmpCorns[5].equals("*") && !tmpCorns[5].equals("?")) {if (tmpCorns[5].contains(",")) {sBuffer.append("每周").append(tmpCorns[5]).append("的");} else {sBuffer.append("每周");char[] tmpArray = tmpCorns[5].toCharArray();for (char tmp : tmpArray) {switch (tmp) {case '1':sBuffer.append("日");break;case '2':sBuffer.append("一");break;case '3':sBuffer.append("二");break;case '4':sBuffer.append("三");break;case '5':sBuffer.append("四");break;case '6':sBuffer.append("五");break;case '7':sBuffer.append("六");break;default:sBuffer.append(tmp);break;}}}}//解析日if (!tmpCorns[3].equals("?")) {if (sBuffer.toString().contains("一") && sBuffer.toString().contains("二") && sBuffer.toString().contains("三")&& sBuffer.toString().contains("四") && sBuffer.toString().contains("五") && sBuffer.toString().contains("六")&& sBuffer.toString().contains("日")) {}if (!tmpCorns[3].equals("*")) {if (tmpCorns[3].contains("/")) {sBuffer.append("每周从第").append(tmpCorns[3].split("/")[0]).append("天开始").append(",每").append(tmpCorns[3].split("/")[1]).append("天");} else {sBuffer.append("每月第").append(tmpCorns[3]).append("天");}}}//解析时if (!tmpCorns[2].equals("*")) {if (tmpCorns[2].contains("/")) {sBuffer.append("从").append(tmpCorns[2].split("/")[0]).append("点开始").append(",每").append(tmpCorns[2].split("/")[1]).append("小时");} else {if (!(sBuffer.toString().length() > 0)) {sBuffer.append("每天").append(tmpCorns[2]).append("点");}else {sBuffer.append(tmpCorns[2]).append("点");}}}//解析分if (!tmpCorns[1].equals("*")) {if (tmpCorns[1].contains("/")) {sBuffer.append("从第").append(tmpCorns[1].split("/")[0]).append("分开始").append(",每").append(tmpCorns[1].split("/")[1]).append("分");} else if (tmpCorns[1].equals("0")) {} else {sBuffer.append(tmpCorns[1]).append("分");}}if (sBuffer.toString().length() > 0) {sBuffer.append("执行一次");} else {sBuffer.append("表达式中文转换异常");}}return sBuffer.toString();}/***    第二种格式*/public  String translateToChinese2(String cronExp){if (cronExp == null || cronExp.length() < 1){return "cron表达式为空";}CronExpression exp = null;// 初始化cron表达式解析器try{exp = new CronExpression(cronExp);}catch (ParseException e){return "corn表达式不正确";}String[] tmpCorns = cronExp.split(" ");StringBuffer sBuffer = new StringBuffer();if(tmpCorns.length == 6){//解析月if(!tmpCorns[4].equals("*")){sBuffer.append(tmpCorns[4]).append("月");}else{sBuffer.append("每周");}//解析周if(!tmpCorns[5].equals("*") && !tmpCorns[5].equals("?")){char[] tmpArray =  tmpCorns[5].toCharArray();for(char tmp:tmpArray){switch (tmp){case '1':sBuffer.append("星期天");break;case '2':sBuffer.append("星期一");break;case '3':sBuffer.append("星期二");break;case '4':sBuffer.append("星期三");break;case '5':sBuffer.append("星期四");break;case '6':sBuffer.append("星期五");break;case '7':sBuffer.append("星期六");break;case '-':sBuffer.append("至");break;default:sBuffer.append(tmp);break;}}}//解析日if(!tmpCorns[3].equals("?")){if(!tmpCorns[3].equals("*")){sBuffer.append(tmpCorns[3]).append("日");}else{sBuffer.append("每日");}}//解析时if(!tmpCorns[2].equals("*")){sBuffer.append(tmpCorns[2]).append("时");}else{sBuffer.append("每时");}//解析分if(!tmpCorns[1].equals("*")){sBuffer.append(tmpCorns[1]).append("分");}else{sBuffer.append("每分");}//解析秒if(!tmpCorns[0].equals("*")){sBuffer.append(tmpCorns[0]).append("秒");}else{sBuffer.append("每秒");}}return sBuffer.toString();}private List<Integer> initArray(Integer num) {List<Integer> result = Lists.newArrayListWithExpectedSize(num);for (int i = 0; i <= num; i++) {result.add(i);}return result;}public List<Integer> turnWeek(List<Integer> week){List<Integer> integers = new ArrayList<>();for (Integer integer : week) {switch (integer) {case 1:integers.add(2);break;case 2:integers.add(3);break;case 3:integers.add(4);break;case 4:integers.add(5);break;case 5:integers.add(6);break;case 6:integers.add(7);break;case 7:integers.add(1);break;default:break;}}return integers;}private List<Integer> getInitMinutes() {return this.initArray(59);}private List<Integer> getInitHours() {return this.initArray(23);}private List<Integer> getInitWeekdays() {return this.initArray(7).subList(1, 8);}@Datapublic static class CustomCronField {private List<Integer> minutes;private List<Integer> hours;private List<Integer> weekdays;}
}

测试一下:

@RestController
@RequestMapping("/cronTest")
public class CronController {finalCronUtils cronUtils;public CronController(CronUtils cronUtils) {this.cronUtils = cronUtils;}@RequestMapping("/cron")public void cron(@RequestParam List<Integer> minutes,@RequestParam  List<Integer> hours,@RequestParam  List<Integer> weekdays){List<Integer> week = cronUtils.turnWeek(weekdays);String cron = cronUtils.buildCron(minutes,hours,week); //输出Cron表达式,周已转换System.out.println(cron);//TODO 周有问题,1:日;2:一;······CronUtils.CustomCronField cronField = cronUtils.parseCon(cron);System.out.println(cronField);  //按格式输出时间System.out.println(cronUtils.translateToChinese(cron));    //输出用户设置的中文格式System.out.println(cronUtils.translateToChinese2(cron));//第二种格式}
}


Java自定义Cron,解析Cron表达式相关推荐

  1. java 自定义json解析注解 复杂json解析 工具类

    java 自定义json解析注解 复杂json解析 工具类 目录 java 自定义json解析注解 复杂json解析 工具类 1.背景 2.需求-各式各样的json 一.一星难度json[json对象 ...

  2. java juel表达式_activiti 自定义函数解析juel表达式

    activiti是支持juel表达式的,这个也很好用,但实际过程中需要支持类方法及变量. 原来项目中解析juel,这边有自定义一个方法的 代码如下: public String getStringBy ...

  3. java自定义注解解析及自定义注解

    jdk1.5之后提供了注解(Annotation)这一种语法.其主要作用是编译检查(比如@override)和代码分析(通过代码中添加注解,利用注解解析器对添加了注解的代码进行分析,获取想要的结果,一 ...

  4. java自定义变量解析,Thymeleaf内置对象、定义变量、URL参数及标签自定义属性

    如标题所述,这篇文章主要讲述Thymeleaf中的内置对象(list解析.日期格式化.数字格式化等).定义变量.获取URL的参数和在页面标签中自定义属性的应用. 如果对Thymeleaf的基本使用.m ...

  5. java自定义注解解析

    开始接触java注解的时候,感觉是个很高深的概念,经过一段时间的学习,对注解有了新的认识,并没有想象的那么复杂. 注解本质上就是一个标记,是给程序看的. 如果自定义了一个注解,但是没有对自定义的注解做 ...

  6. java 自定义注解 解析_java自定义注解

    1.Annotation的工作原理: JDK5.0中提供了注解的功能,允许开发者定义和使用自己的注解类型.该功能由一个定义注解类型的语法和描述一个注解声明的语法,读取注解的API,一个使用注解修饰的c ...

  7. JAVA自定义协议解析

    在JAVA中, 一般来说自定义协议都是涉及到物联网平台.字节数组和对象操作特别多. 使用netty, 然后使用byteBuffer 进行解包 或者 封包操作. 平时来说这个是没什么问题的. 但是 很多 ...

  8. java 自定义语言 解析_视频讲解 Java 语言基础编程题(自定义异常类,IO 流)

    第一题>点击这里查看学生信息管理系统的视频讲解知乎视频​www.zhihu.com 基于学生信息管理系统增加以下两个功能:自定义学号异常类和年龄异常类,并在该成员变量不合理时产生异常对象并抛出. ...

  9. java 解析cron_Java 解析Cron表达式,获取最近运行时间

    摘要:Java 解析Cron表达式,获取最近运行时间 方法一 package com.odj.customer.index.controller; import java.text.ParseExce ...

最新文章

  1. Java--------------Mysql中时间按要求查询
  2. 房价越高的地方资产越高?北京户均资产890万?
  3. 阿里云服务器上安装java配置jdk
  4. ELDataQuery 基于.NET 2.0的数据查询框架 雏型
  5. pythonhelloworld项目,10分钟搭建一个小型网页(python django)(hello world!)
  6. DOM操作与引用资源的前后关系
  7. 各种语言和各种前沿技术的简介和科普
  8. 转载:别人使用的工具
  9. 软件开发模式有哪些?
  10. WPS JSA 学习笔记
  11. STM32F103_study67_The punctual atoms(STM32 OLED display experiment)
  12. android pppd参数介绍,android 3G pppd 调试记录
  13. js获取系统当前时间,实现钟表功能
  14. 浩辰3D软件新手入门攻略:草图绘制功能全解析!
  15. 通过google插件Thumbnails实现图片指定大小压缩
  16. python语言基本语句-Python中的基本语句
  17. STM32G0和STM32G4 如何把BOOT0当作通用GPIO使用
  18. 软考网络工程师上午考试知识点总结整理
  19. 实用的60个CSS代码片段
  20. win10系统用什么测试软件,Win10系统如何测试软件兼容性?

热门文章

  1. ht1621b和单片机电平匹配_关于ht1621的使用和初始化....
  2. c语言编程实现表达式求值,c语言实现表达式求值的方法
  3. 哪些食物是益生菌的最佳补充剂
  4. Android 橡皮擦功能,图层混合模式PorterDuff.Mode实践
  5. textBox控件无法改变高度
  6. 《光明传说》主城建筑图文详解の光之塔
  7. 德芙巧克力诞生的背后,有一个悲情的爱情故事。
  8. java8——Optinal类
  9. 浅谈当今主流笔记本的cpu
  10. PHP代码 之create_function()函数