在使用定时器 quartz 时,其中的cron 表达式,老板表示作为开发的你能看懂外,其他的非开发同事可能看不懂,要用一个他们能看懂的方式表达出来。
还好我们的项目要求的表达式不是特别的麻烦,所以就写了一个简略的转换为中文的方法
package com.common.utils; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import org.quartz.CronExpression; public class CronExpParser { /** * 解析corn表达式,生成指定日期的时间序列 * * @param cronExpression cron表达式 * @param cronDate cron解析日期 * @param result crom解析时间序列 * @return 解析成功失败 */ public static boolean parser(String cronExpression, String cronDate, List<String> result) { if (cronExpression == null || cronExpression.length() < 1 || cronDate == null || cronDate.length() < 1) { return false; } else { CronExpression exp = null; // 初始化cron表达式解析器 try { exp = new CronExpression(cronExpression); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); return false; } // 定义生成时间范围 // 定义开始时间,前一天的23点59分59秒 Calendar c = Calendar.getInstance(); String sStart = cronDate + " 00:00:00"; SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date dStart = null; try { dStart = sdf.parse(sStart); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } c.setTime(dStart); c.add(Calendar.SECOND, -1); dStart = c.getTime(); // 定义结束时间,当天的23点59分59秒 c.add(Calendar.DATE, 1); Date dEnd = c.getTime(); // 生成时间序列 java.util.Date dd = dStart; dd = exp.getNextValidTimeAfter(dd); while ((dd.getTime() >= dStart.getTime()) && (dd.getTime() <= dEnd.getTime())) { result.add(sdf.format(dd)); dd = exp.getNextValidTimeAfter(dd); } exp = null; } return true; } public static String translateToChinese(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(); } //测试方法 public static void main(String[] args) { String CRON_EXPRESSION = "0 0 3 * * ?"; // 生成指定日期的CRON时间序列 String CRON_DATE = "2016-04-26"; System.out.println(CRON_EXPRESSION); System.out.println(CronExpParser.translateToChinese(CRON_EXPRESSION)); List<String> lTime = new ArrayList<String>(); if(!CronExpParser.parser(CRON_EXPRESSION, CRON_DATE, lTime)){ System.out.println("无法生成Cron表达式:日期,"+CRON_DATE+";不符合规则cron表达式:"+CRON_EXPRESSION); } for(int i=0;i<lTime.size();i++){ System.out.println(lTime.get(i)); } } }
执行结果:
0 0 3 * * ? 每月每日3时0分0秒 2016-04-26 03:00:00
老板说界面也不能直接让她们写表达式,最好是能有直观的感受去选,
于是我设计的界面如下:可以手动修改执行时间,或者可以使用cron表达式界面去修改,执行日期修改时 描述信息也将修改
<tr><td align="right">
执行时间:
</td>
<td>
<input id="cron" class="tr180 td26" value="" name="cron" type="text" onchange="checkCron();"><img src="./images/form/clock.gif" onclick="openCron()">
<div >说明:设置定时器调度的时程表格式 <b>秒</b>(0-59,*) <b>分</b>(0-59,*) <b>时</b>(0-23,*) <b>日</b>(0-31,*,?) <b>月</b>(0-11) <b>周</b>(1-7,*,? 1=SUN) /指数值的增量<br>示例① 0 0 12 * * ? 例② 0 15,16 10 15 * ? 例③ 0 15 10 ? * 2-6</div>
</td>
</tr>
<tr>
<td align="right">
执行时间描述:
</td>
<td>
<div id="cronDesc"></div>
</td>
</tr>
用一个 onchange 方法,调用一个 ajax 就可以实现描述的 更新啦
function checkCron() { var datas={ "cronExp":$("#cron").val() }; $.ajax({ type: "post", url: "/getCronDesc", data: datas, datatype: "text", success:function(data){ //成功的处理函数 $("#cronDesc").html(data); } }); }
而 Cron 表达式的页面效果,找了好久,终于看到想看的东西了。感谢 网友的无私分享,在他的基础之上,我经过修改改成自己需要的了,效果如下。
打开一个新的页面
openWin("../../static/cron/cronindex.htm", 640, 480); function openWin(url,width,height) { var newwin = window.open(url,"_blank","scrollbars=yes,resizable=yes,toolbar=no,location=no,directories=no,status=no,menubar=no,top=50,left=120,width="+width+",height="+height); }
在打开的页面上选中值后,关闭子页面,并给父页面的某个表单赋值,调用父页面的某个js 方法
function selCron() { //获取选中的选择框的值 var cron = $("#cron").val(); window.opener.cron.value=cron; window.close(); window.opener.checkCron(); }
(ps: 居然不知道 附件怎么上传,算了,corn 页面我就不写了,自己去找吧)