github地址:https://github.com/VioletSY/cron-js
cron表達式可以使用js生成,也可以使用后台代碼生成,這里采用js的方式
(1)Cron.js
var __$ = { create: function () { return function () { this.initialize.apply(this, arguments); } }, extend: function (destination, source) { for (var property in source) { destination[property] = source[property]; } return destination; } }; /* * 創建SimpleTime類,用於對3種格式的時間進行處理 * 初始化時入參為時間字符串形如 * 1.yyyy-mm-dd hh:MM:ss * 2.yyyy-mm-dd * 3.hh:MM:ss * 內建6個字段:year,month,day,hour,minute,second * 內建6個字段的get方法,符合java命名規范 * 注意: * 1.日期輸入需要校驗格式,內部沒有校驗格式 * 2.初始化串形如yyyy-mm-dd和hh:MM:ss時,get沒有值的域會返回undefined */ var SimpleTime = __$.create(); __$.extend(SimpleTime.prototype, { initialize: function (time) { time = time || ""; switch (time.length) { case 8: this.timeAry = ['', '', ''].concat(time.split(":")); break; case 10: this.timeAry = time.split("-").concat(['', '', '']); break; case 19: this.timeAry = time.split(/[:| |-]/g); break; default: this.timeAry = []; } }, getYear: function () { return this.timeAry[0] ? this.timeAry[0].replace(/^0/g, "") : this.timeAry[0]; }, getMonth: function () { return this.timeAry[1] ? this.timeAry[1].replace(/^0/g, "") : this.timeAry[1]; }, getDay: function () { return this.timeAry[2] ? this.timeAry[2].replace(/^0/g, "") : this.timeAry[2]; }, getHour: function () { return this.timeAry[3] ? this.timeAry[3].replace(/^0/g, "") : this.timeAry[3]; }, getMinute: function () { return this.timeAry[4] ? this.timeAry[4].replace(/^0/g, "") : this.timeAry[4] }, getSecond: function () { return this.timeAry[5] ? this.timeAry[5].replace(/^0/g, "") : this.timeAry[5]; } } ); /* * Cron表達式中內建的域對象,封裝了域的操作方法 * 初始化時通過type初始化類型,對應的操作域操作方法如下: * setBase:接受一個參數,用於設置域基值 * inc:增量,接受一個參數incr,每隔incr時間 * any:任意時刻,即* * manual:接受參數str,手動輸入,用於輸入比較復雜的域值str * ask:問號,日域或星期域有一個必然是? * last:將當前域設置成按倒數,如果輸入參數則為倒數第幾天,如果不輸入參數,按setBase的值計算 * nolast:刪除last屬性 * workDay:日域是否為工作日,如果輸入參數則為第幾個工作日,如果不輸入參數,按setBase的值計算 * noWorkDay:刪除工作日屬性 * selectWeek:第幾周的周幾,接受兩個參數,week代表第幾周,weekDay代表星期幾 * toDomainStr:返回此域的Cron表達式域字符串 */ var _Domain = __$.create(); __$.extend(_Domain.prototype, { initialize: function (arg, type) { this.type = type; this.base = arg || "0"; if (type == 'weekDay' || type == 'day' || type == 'month') { this.base = this.base == "0" ? 1 : this.base; } if (!arg) { this.anyType = true; return; } }, setBase: function (baseStr) { this.base = baseStr; }, inc: function (incr) { delete this.anyType; delete this.askType; delete this.manualType; this.incStep = incr; }, any: function () { delete this.incStep; delete this.askType; delete this.manualType; this.anyType = true; }, manual: function (str) { delete this.incStep; delete this.anyType; delete this.askType; this.manualType = true; this.manualStr = str; }, ask: function () { delete this.anyType; delete this.incStep; delete this.manualType; this.askType = true; }, last: function (num) { delete this.askType; delete this.anyType; if (typeof num != "undefined") { this.base = num + ""; } var newBase = (this.base.match(/[\d]+/) || [this.base][0]) + "L"; this.base = newBase == "1L" ? "L" : newBase; }, nolast: function () { this.base = this.base.replace(/L$/, ""); }, workDay: function (num) { delete this.askType; delete this.anyType; if (typeof num != "undefined") { this.base = num + ""; } this.base = (this.base.match(/[\d]+/) || [this.base][0]) + "W"; }, noworkDay: function () { this.base = this.base.replace(/W$/, ""); }, selectWeek: function (week, weekDay) { this.manual(week + "#" + weekDay); }, toDomainStr: function () { if (this.anyType) { return "*"; } if (this.incStep) { return this.base + "/" + this.incStep; } if (this.manualType) { return this.manualStr; } if (this.askType) { return "?"; } return this.base; } } ) /* * Cron表達式類對象 * 初始化時入參為時間字符串形如 * 1.yyyy-mm-dd hh:MM:ss * 2.yyyy-mm-dd * 3.hh:MM:ss * 內建7個域:year,weekDay,month,day,hour,minute,second * 可以通過Cron的實例對象.domain[域].方法(參數)訪問指定域的指定方法 * 可以通過內建的set方法訪問 * 內建方法: * set:可以通過Cron的實例對象.set('域','方法',參數1,[...,參數n])訪問指定域的指定方法 * toCron:返回當前Cron表達式對象的Cron表達式串 * 注意: * 1.日期輸入需要校驗格式,內部沒有校驗格式 * 2.weekDay域中,初始化后為? * 3.設置day域時,weekDay域會自動轉換為?,反之亦然 * 4.具體域方法見_Domain類的內建方法 */ var Cron = __$.create(); Cron.pack = function (input) { var lines = []; var line = [input[0]]; for (var i = 1; i < input.length; i++) { if (line.length == 0 || input[i] - 1 == line[line.length - 1]) { line.push(input[i]); } else { lines.push(line); line = [input[i]]; } } lines.push(line); for (var i = 0; i < lines.length; i++) { lines[i] = lines[i].length > 2 ? lines[i].shift() + "-" + lines[i].pop() : lines[i].join(","); } return lines.join(","); } __$.extend(Cron.prototype, { initialize: function (baseTime) { this.time = new SimpleTime(baseTime); this.domain = { hour: new _Domain(this.time.getHour(), "hour"), minute: new _Domain(this.time.getMinute(), "minute"), second: new _Domain(this.time.getSecond(), "second"), day: new _Domain(this.time.getDay(), "day"), month: new _Domain(this.time.getMonth(), "month"), weekDay: new _Domain(null, "weekDay"), year: new _Domain(this.time.getYear(), "year") } this.domain.weekDay.ask(); }, toCron: function () { var domainAry = []; domainAry.push(format(this.domain['second'].toDomainStr())); domainAry.push(format(this.domain['minute'].toDomainStr())); domainAry.push(format(this.domain['hour'].toDomainStr())); domainAry.push(format(this.domain['day'].toDomainStr())); domainAry.push(format(this.domain['month'].toDomainStr())); domainAry.push(this.domain['weekDay'].toDomainStr()); domainAry.push(this.domain['year'].toDomainStr()); return domainAry.join(" "); }, set: function (domain, operationType) { if (domain == "weekDay" && (operationType != "ask")) { this.domain['day']["ask"](); } else if (domain == "day" && (operationType != "ask")) { this.domain['weekDay']["ask"](); } var args = []; for (var i = 2; i < arguments.length; i++) { args.push(arguments[i]); } this.domain[domain][operationType].apply(this.domain[domain], args); } } ) function format (val) { if (val < 10) { return "0" + val } return val }
(2)參數封裝scheduler.js
function getCronExpression (onceTime,cron,startTime, cycle, hourFlag, minuteFlag, interValDay, endTime, hourInterval, minuteInterval, weekArray, MonthArray, day) { var cronExpression = ""; if (cycle == "1") { cronExpression = getCronByStartTime(onceTime); } else if (cycle == "5") { cronExpression = getCronBySelf(cron); } else { cronExpression = getCronByTimePoint(startTime, cycle, hourFlag, minuteFlag, interValDay, endTime, hourInterval, minuteInterval, weekArray, MonthArray, day); } return cronExpression; } //onlyOne function getCronByStartTime (startTime) { var _startTime = new SimpleTime(startTime); var cron = ""; cron = new Cron(startTime); return cron.toCron(); } //selfDef function getCronBySelf (cron) { if (cron == null || cron == "") { return; } return cron; } //getCronByTimePoint function getCronByTimePoint (timePoint, planType, hourFlag, minuteFlag, interValDay, endTime, hourInt, minuteInt, weekDayArr, selectMonth, day) { endTime = endTime || timePoint; var cron = ""; if (planType == "2") { cron = createCronByTimePoint(timePoint, hourFlag, minuteFlag, endTime, hourInt, minuteInt); cron.set('day', 'setBase', '*'); cron.set('day', 'inc', interValDay + ""); } else if (planType == "3") { var selectedDays = Cron.pack(weekDayArr); if (selectedDays == "") { selectedDays = "1-7"; } cron = createCronByTimePoint(timePoint, hourFlag, minuteFlag, endTime, hourInt, minuteInt); cron.set('weekDay', 'manual', selectedDays); } else if (planType == "4") { cron = createCronByTimePoint(timePoint, hourFlag, minuteFlag, endTime, hourInt, minuteInt); cron.set('month', 'manual', selectMonth); day == "-1" ? cron.set('day', 'last', 1) : cron.set('day', 'manual', day); } return cron.toCron(); } function createCronByTimePoint (timePoint, hourFlag, minuteFlag, endTime, hourInt, minuteInt) { var cron = new Cron(timePoint); if (endTime) { var timeAry = endTime.split(":"); if (timeAry[0].charAt(0) == "0") { timeAry[0] = timeAry[0].charAt(1); } cron.set('hour', 'setBase', timePoint.split(":")[0].replace(/^0/g, "") + "-" + timeAry[0]); } if (minuteFlag) { cron.set('minute', 'inc', minuteInt); } else if (hourFlag) { cron.set('hour', 'inc', hourInt); } return cron; }
(3)測試
<script> var cycle = "1";//周期類型 //第一種形式 cycle等於1:指定時間點 var timePoint = "2020-04-01 15:50:27";//時間點 //第二種形式 cycle等於2:以天為間隔 var startTime = "06:15:15";//開始時間 var endTime = "10:15:15";//結束時間 var hourFlag = false;//是否以分鍾為間隔 var minuteFlag = true;//是否以分鍾為間隔 var interValDay = 3;//間隔天數 var hourInterval = 4;//間隔小時數 var minuteInterval= 3;//間隔分鍾數 //第三種形式 cycle等於3:以周為間隔 var weekArray = ['2','4'];//指定每周周幾 //第四種形式 cycle等於4:以月為間隔 var MonthArray = [4,7];//指定那幾個月份 var day =21;//指定哪天 //第五種形式 cycle等於5:指定表達式 var cron = "0/1 * * * * ? ";//Cron表達式 var cronExpression = getCronExpression(timePoint,cron,startTime, cycle, hourFlag, minuteFlag, interValDay, endTime, hourInterval, minuteInterval, weekArray, MonthArray, day); console.log(cronExpression) </script>