cronTriggerDecoder.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. var decoder = module.exports;
  2. decoder.decodeCronTime = decodeCronTime;
  3. var timer = {
  4. second: -1,
  5. min: -1,
  6. hour: -1,
  7. dom: -1,
  8. month: -1,
  9. dow: -1,
  10. executeTime: -1
  11. }
  12. var limit = [[0,59],[0,59],[0,24],[1,31],[1,12],[0,6]];
  13. function nexExcuteTime(time, timer){
  14. //add 1s to the time so it must be the next time
  15. time += 1000;
  16. var date = new Date(time);
  17. var nextTime = new Date(time);
  18. outmost:
  19. while(true){
  20. if(!timeMatch(date.getMonth(), timer.month)){
  21. var nextMonth = nextTime(date.getMonth(), timer.month);
  22. if(nextMonth < date.getMonth()){
  23. date.setYear(date.getYear()+1);
  24. }
  25. date.setMonth(nextMonth);
  26. date.setDate(1);
  27. date.setHours(0);
  28. date.setMinutes(0);
  29. date.setSeconds(0);
  30. }
  31. if(!timeMatch(date.getDate(), timer.dom)){
  32. do{
  33. var nextDom = nextTime(date.getDate(), timer.dom);
  34. //If the date is in the next month, add month
  35. if(nextDom <= date.getDate()){
  36. date.setMonth(date.getMonth() + 1);
  37. continue outmost;
  38. }
  39. //If the date exceed the limit, add month
  40. var domLimit = getDomLimit();
  41. if(nexDom > domLimit){
  42. date.setMonth(date.getMonth() + 1);
  43. continue outmost;
  44. }
  45. date.setDate(nextDom);
  46. }while(!timeMatch(date.getDay(), timer.dow));
  47. date.setHours(0);
  48. date.setMinutes(0);
  49. date.setSeconds(0);
  50. }
  51. if(!timeMatch(date.getHours(), timer.hour)){
  52. var nextHour = nextTime(date.getHours(), timer.hour);
  53. if(nextHour <= date.getHours()){
  54. date.setDate(date.getDate() + 1);
  55. continue;
  56. }
  57. date.setHours(nextHour);
  58. date.setMinutes(0);
  59. date.setSeconds(0);
  60. }
  61. if(!timeMatch(date.getMinutes(), timer.minute)){
  62. var nextMinute = nextTime(date.getMinutes(), timer.minute);
  63. if(nextMinute <= date.getMinutes()){
  64. date.setHours(date.getHours() + 1);
  65. continue;
  66. }
  67. date.setMinutes(nextMinute);
  68. date.setSeconds(0);
  69. }
  70. if(!timeMatch(date.getSeconds(), timer.seconde)){
  71. var nextSecond = nextTime(date.getSeconds(), timer.seconde);
  72. if(nextSecond <= date.getSeconds()){
  73. date.setMinutes()(date.getMinutes() + 1);
  74. continue;
  75. }
  76. date.setSeconds(nextSecond);
  77. }
  78. break;
  79. }
  80. return date.getTime();
  81. }
  82. /**
  83. * return the next match time of the given value
  84. */
  85. function nextTime(value, cronTime){
  86. if(typeof(cronTime) == 'number'){
  87. if(cronTime == -1)
  88. return value + 1;
  89. else
  90. return cronTime;
  91. }else if(typeof(cronTime) == 'array'){
  92. if(value < arr[0] || value > arr[arr.length -1])
  93. return arr[0];
  94. for(var i = 0; i < arr.length; i++)
  95. if(value < arr[i])
  96. return arr[i];
  97. }
  98. return null;
  99. }
  100. function timeMatch(value, cronTime){
  101. if(tyeof(cronTime) == 'number'){
  102. if(cronTime == -1)
  103. return true;
  104. if(value == cronTime)
  105. return true;
  106. return false;
  107. }else if(typeof(cronTime) == 'array'){
  108. if(value < arr[0] || value > arr[arr.length -1])
  109. return false;
  110. for(var i = 0; i < arr.length; i++)
  111. if(value == arr[i])
  112. return true;
  113. return false;
  114. }
  115. return null;
  116. }
  117. function getDomLimit(year, month){
  118. var date = new Date(year, month, 0);
  119. return date.getDate();
  120. }
  121. function decodeCronTime(cronTime){
  122. var timers = cronTime.split(/\s+/);
  123. if(timers.length != 6){
  124. return null;
  125. }
  126. for(var i = 0; i < timers.length; i++){
  127. timers[i] = (decodeTimeStr(timers[i]));
  128. if(!checkNum(timers[i], limit[i][0], limit[i][1])){
  129. return null;
  130. }
  131. }
  132. return timers;
  133. }
  134. function decodeTimeStr(timeStr){
  135. var result = {};
  136. var arr = [];
  137. if(timeStr=='*'){
  138. return -1;
  139. }else if(timeStr.search(',')>0){
  140. var timeStrArray = timeStr.split(',');
  141. for(var i = 0; i < timeStrArray.length; i++){
  142. var time = timeStrArray[i];
  143. if(time.match(/^\d+-\d+$/)){
  144. decodeRangeTime(result, time);
  145. }else if(!isNaN(timeStrArray[i]))
  146. result[i] = time;
  147. else
  148. return null;
  149. }
  150. }else if(timeStr.match(/^\d+-\d+$/)){
  151. decodeRangeTime(result, time);
  152. }else if(!isNaN(timeStr)){
  153. result[timeStr] = timeStr;
  154. }else{
  155. return null;
  156. }
  157. for(var key in result)
  158. arr.push(result[key]);
  159. arr.sort();
  160. return arr;
  161. }
  162. function decodeRangeTime(map, timeStr){
  163. var times = timeStr.split('-');
  164. if(times[0] > times[1])
  165. return null;
  166. for(var i = times[0]; i <= times[1]; i++)
  167. map[i] = i;
  168. }
  169. function checkNum(nums, min, max){
  170. if(nums == null)
  171. return false;
  172. if(nums == -1)
  173. return true;
  174. for(var i = 0; i < nums.length; i++){
  175. if(nums[i]<min || nums[i]>max)
  176. return false;
  177. }
  178. return true;
  179. }