123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- var decoder = module.exports;
- decoder.decodeCronTime = decodeCronTime;
- var timer = {
- second: -1,
- min: -1,
- hour: -1,
- dom: -1,
- month: -1,
- dow: -1,
- executeTime: -1
- }
- var limit = [[0,59],[0,59],[0,24],[1,31],[1,12],[0,6]];
- function nexExcuteTime(time, timer){
- //add 1s to the time so it must be the next time
- time += 1000;
- var date = new Date(time);
- var nextTime = new Date(time);
- outmost:
- while(true){
- if(!timeMatch(date.getMonth(), timer.month)){
- var nextMonth = nextTime(date.getMonth(), timer.month);
- if(nextMonth < date.getMonth()){
- date.setYear(date.getYear()+1);
- }
- date.setMonth(nextMonth);
-
- date.setDate(1);
- date.setHours(0);
- date.setMinutes(0);
- date.setSeconds(0);
- }
-
- if(!timeMatch(date.getDate(), timer.dom)){
- do{
- var nextDom = nextTime(date.getDate(), timer.dom);
-
- //If the date is in the next month, add month
- if(nextDom <= date.getDate()){
- date.setMonth(date.getMonth() + 1);
- continue outmost;
- }
-
- //If the date exceed the limit, add month
- var domLimit = getDomLimit();
- if(nexDom > domLimit){
- date.setMonth(date.getMonth() + 1);
- continue outmost;
- }
-
- date.setDate(nextDom);
- }while(!timeMatch(date.getDay(), timer.dow));
-
- date.setHours(0);
- date.setMinutes(0);
- date.setSeconds(0);
- }
-
- if(!timeMatch(date.getHours(), timer.hour)){
- var nextHour = nextTime(date.getHours(), timer.hour);
-
- if(nextHour <= date.getHours()){
- date.setDate(date.getDate() + 1);
- continue;
- }
-
- date.setHours(nextHour);
- date.setMinutes(0);
- date.setSeconds(0);
- }
-
- if(!timeMatch(date.getMinutes(), timer.minute)){
- var nextMinute = nextTime(date.getMinutes(), timer.minute);
-
- if(nextMinute <= date.getMinutes()){
- date.setHours(date.getHours() + 1);
- continue;
- }
-
- date.setMinutes(nextMinute);
- date.setSeconds(0);
- }
-
- if(!timeMatch(date.getSeconds(), timer.seconde)){
- var nextSecond = nextTime(date.getSeconds(), timer.seconde);
-
- if(nextSecond <= date.getSeconds()){
- date.setMinutes()(date.getMinutes() + 1);
- continue;
- }
-
- date.setSeconds(nextSecond);
- }
-
- break;
- }
-
- return date.getTime();
- }
- /**
- * return the next match time of the given value
- */
- function nextTime(value, cronTime){
- if(typeof(cronTime) == 'number'){
- if(cronTime == -1)
- return value + 1;
- else
- return cronTime;
- }else if(typeof(cronTime) == 'array'){
- if(value < arr[0] || value > arr[arr.length -1])
- return arr[0];
-
- for(var i = 0; i < arr.length; i++)
- if(value < arr[i])
- return arr[i];
- }
-
- return null;
- }
- function timeMatch(value, cronTime){
- if(tyeof(cronTime) == 'number'){
- if(cronTime == -1)
- return true;
- if(value == cronTime)
- return true;
- return false;
- }else if(typeof(cronTime) == 'array'){
- if(value < arr[0] || value > arr[arr.length -1])
- return false;
-
- for(var i = 0; i < arr.length; i++)
- if(value == arr[i])
- return true;
-
- return false;
- }
-
- return null;
- }
- function getDomLimit(year, month){
- var date = new Date(year, month, 0);
-
- return date.getDate();
- }
- function decodeCronTime(cronTime){
- var timers = cronTime.split(/\s+/);
-
- if(timers.length != 6){
- return null;
- }
-
- for(var i = 0; i < timers.length; i++){
- timers[i] = (decodeTimeStr(timers[i]));
-
- if(!checkNum(timers[i], limit[i][0], limit[i][1])){
- return null;
- }
- }
-
- return timers;
- }
- function decodeTimeStr(timeStr){
- var result = {};
- var arr = [];
-
- if(timeStr=='*'){
- return -1;
- }else if(timeStr.search(',')>0){
- var timeStrArray = timeStr.split(',');
- for(var i = 0; i < timeStrArray.length; i++){
- var time = timeStrArray[i];
- if(time.match(/^\d+-\d+$/)){
- decodeRangeTime(result, time);
- }else if(!isNaN(timeStrArray[i]))
- result[i] = time;
- else
- return null;
- }
- }else if(timeStr.match(/^\d+-\d+$/)){
- decodeRangeTime(result, time);
- }else if(!isNaN(timeStr)){
- result[timeStr] = timeStr;
- }else{
- return null;
- }
-
- for(var key in result)
- arr.push(result[key]);
-
- arr.sort();
-
- return arr;
- }
- function decodeRangeTime(map, timeStr){
- var times = timeStr.split('-');
-
- if(times[0] > times[1])
- return null;
- for(var i = times[0]; i <= times[1]; i++)
- map[i] = i;
- }
- function checkNum(nums, min, max){
- if(nums == null)
- return false;
-
- if(nums == -1)
- return true;
-
- for(var i = 0; i < nums.length; i++){
- if(nums[i]<min || nums[i]>max)
- return false;
- }
-
- return true;
- }
|