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