接續第一篇(頁面配置),本文深入解析如何將前端收集的多維排程參數(頻率、具體時間、星期、日期等)轉換為標準 Unix Cron Expression。這是動態排程系統中最核心、邏輯最複雜的環節。
ActionForm 收集的關鍵字段:
everyWhat:頻率類型 — monthly(每月)、weekly(每週)、userDefined(自定義日期)commonNeeds:[秒, 分, 時] — 所有模式共用monthlyNeeds:[第幾週(1-4), 星期幾(1-7)] — 每月模式專用weeklyNeeds:星期幾(1-7) — 每週模式專用userDefinedNeeds:yyyy-MM-dd — 自定義日期模式專用CronExpConversionpublic class CronExpConversion {
// 特殊字符常量
static class CronExRelated {
static final String _ANY = "*";
static final String _EVERY = "?";
static final String _THENTH = "#"; // 第幾個星期幾
static Map<String, String> specialCharacters = Map.of(
"_ANY", "*", "_EVERY", "?", "_THENTH", "#"
);
}
public static String convertDateToCronExp(String everyWhat,
String[] commonNeeds, String[] monthlyNeeds,
String weeklyNeeds, String userDefinedNeeds) {
String commons = String.join(" ", commonNeeds) + " "; // 秒 分 時
if ("monthly".equals(everyWhat)) {
// 格式:秒 分 時 ? 月 第幾週#星期幾
// 例:0 30 10 ? 1/1 6#3 (每月第三個週五 10:30)
String dayOfWeek = monthlyNeeds[1] + "#" + monthlyNeeds[0];
return (commons + "* " + dayOfWeek).trim();
} else if ("weekly".equals(everyWhat)) {
// 格式:秒 分 時 ? * 星期幾
return (commons + "* " + weeklyNeeds).trim();
} else if ("userDefined".equals(everyWhat)) {
// 格式:秒 分 時 日 月 ?
String[] parts = userDefinedNeeds.split("-");
String year = parts[0]; // Quartz Cron 不支持年份,忽略
String month = parts[1].replaceFirst("^0", "");
String day = parts[2].replaceFirst("^0", "");
return (commons + day + " " + month + " ?").trim();
}
return "";
}
}
| 模式 | Cron 結構 | 關鍵字段含義 |
|---|---|---|
| 每月 | 秒 分 時 ? 月 星期#第幾週 | 用 # 指定「第 N 個星期幾」,? 佔位「日」 |
| 每週 | 秒 分 時 ? * 星期 | * 表示每月,? 佔位「日」 |
| 自定義 | 秒 分 時 日 月 ? | 具體日期,年份被 Quartz 忽略 |
month/day 需去除前導零(replaceFirst("^0", "")),否則 Quartz 解析報錯。Calendar 一致。? **與** *:? 用於「日」與「星期」互斥字段,表示「無具體值」。@Test
public void testMonthly() {
String[] common = {"0", "30", "10"}; // 10:30:00
String[] monthly = {"3", "6"}; // 第3週 的 週五(6)
String cron = CronExpConversion.convertDateToCronExp("monthly", common, monthly, null, null);
assertEquals("0 30 10 ? * 6#3", cron);
}
掌握此轉換邏輯,即可構建強大的可視化排程配置介面,讓非技術人員也能輕鬆維護定時任務。