diff --git a/lib/cron.js b/lib/cron.js index d2051203..5de922c1 100644 --- a/lib/cron.js +++ b/lib/cron.js @@ -124,16 +124,9 @@ return date; } - //add 1 second so next time isn't now (can cause timeout to be 0 or negative number) var now = new Date(); var targetSecond = date.seconds(); var diff = Math.abs(targetSecond - now.getSeconds()) - // there was a problem when `date` is 1424777177999 and `now` is 1424777178000 - // 1 ms diff but this is another second... - if ( diff == 0 || (diff == 1 && now.getMilliseconds() <= date.milliseconds() ) ) { - //console.log('add 1 second?'); - date = date.add(1, 's'); - } //If the i argument is not given, return the next send time if (isNaN(i) || i < 0) { @@ -146,8 +139,7 @@ for (; i > 0; i--) { date = this._getNextDateFrom(date); dates.push(moment(date)); - if (i > 1) - date.add(1,'s'); + } return dates; @@ -181,14 +173,22 @@ /** * get next date that matches parsed cron time */ - _getNextDateFrom: function(start) { - var date = moment(start); + + _getNextDateFrom: function(start,zone) { + var date; + var firstDate=moment(start).valueOf(); + if(zone){ + date=moment(start).tz(zone); + } + else{ + date = moment(start); + } if (!this.realDate) { - const milliseconds = (start.milliseconds && start.milliseconds()) || (start.getMilliseconds && start.getMilliseconds()) || 0; - if (milliseconds > 0) { - date.milliseconds(0); - date.seconds(date.seconds() + 1); - } + const milliseconds = (start.milliseconds && start.milliseconds()) || (start.getMilliseconds && start.getMilliseconds()) || 0; + if (milliseconds > 0) { + date.milliseconds(0); + date.seconds(date.seconds() + 1); + } } if (date.toString() == 'Invalid date') { @@ -209,7 +209,7 @@ var diff = date - start, origDate = new Date(date); - if (!(date.month() in this.month)) { + if (!(date.month() in this.month) && Object.keys(this.month).length!=12) { date.add(1, 'M'); date.date(1); date.hours(0); @@ -217,8 +217,7 @@ date.seconds(0); continue; } - - if (!(date.date() in this.dayOfMonth)) { + if (!(date.date() in this.dayOfMonth) && Object.keys(this.dayOfMonth).length!=31) { date.add(1, 'd'); date.hours(0); date.minutes(0); @@ -226,7 +225,7 @@ continue; } - if (!(date.day() in this.dayOfWeek)) { + if (!(date.day() in this.dayOfWeek) && Object.keys(this.dayOfWeek).length!=7) { date.add(1, 'd'); date.hours(0); date.minutes(0); @@ -236,8 +235,7 @@ } continue; } - - if (!(date.hours() in this.hour)) { + if (!(date.hours() in this.hour) && Object.keys(this.hour).length!=24) { origDate = moment(date); date.hours(date.hours() == 23 && diff > 86400000 ? 0 : date.hours() + 1); date.minutes(0); @@ -247,8 +245,7 @@ } continue; } - - if (!(date.minutes() in this.minute)) { + if (!(date.minutes() in this.minute) && Object.keys(this.minute).length!=60) { origDate = moment(date); date.minutes(date.minutes() == 59 && diff > 60 * 60 * 1000 ? 0 : date.minutes() + 1); date.seconds(0); @@ -257,8 +254,7 @@ } continue; } - - if (!(date.seconds() in this.second)) { + if (!(date.seconds() in this.second) && Object.keys(this.second).length!=60) { origDate = moment(date); date.seconds(date.seconds() == 59 && diff > 60 * 1000 ? 0 : date.seconds() + 1); if (date <= origDate) { @@ -267,6 +263,11 @@ continue; } + if(date.valueOf() === firstDate){ + date.seconds(date.seconds()+1); + continue; + } + break; } diff --git a/tests/test-crontime.js b/tests/test-crontime.js index 38b8f5bf..d2446659 100644 --- a/tests/test-crontime.js +++ b/tests/test-crontime.js @@ -202,4 +202,34 @@ describe('crontime', function () { var x = cronTime._getNextDateFrom(new Date("2018-08-10T02:19:59.999Z")); expect(x.toISOString()).to.equal('2018-08-10T02:20:00.000Z'); }); + + it('should generete the right next days when cron is set to every minute', function () { + var cronTime = new cron.CronTime('* * * * *'); + var min=60000; + var previousDate=new Date(Date.UTC(2018,5,3,0,0)); + for(var i=0;i<25;i++){ + var nextDate = cronTime._getNextDateFrom(previousDate); + expect(nextDate.valueOf()).to.equal(previousDate.valueOf()+min) + previousDate=nextDate; + } + }); + + it('should generete the right next days when cron is set to every 15 min', function () { + var cronTime = new cron.CronTime('*/15 * * * *'); + var min=60000*15; + var previousDate=new Date(Date.UTC(2016,6,3,0,0)); + for(var i=0;i<25;i++){ + var nextDate = cronTime._getNextDateFrom(previousDate); + expect(nextDate.valueOf()).to.equal(previousDate.valueOf()+min) + previousDate=nextDate; + } + }); + + it('should generete the right next day when cron is set to every 15 min in Feb', function () { + var cronTime = new cron.CronTime('*/15 * * FEB *'); + var min=60000*15; + var previousDate=new Date(Date.UTC(2018,3,0,0,0)); + var nextDate = cronTime._getNextDateFrom(previousDate,"UTC"); + expect(nextDate.valueOf()).to.equal(new Date(Date.UTC(2019,1,1,0,0)).valueOf()); + }); });