在使用定時器 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 頁面我就不寫了,自己去找吧)