later icon indicating copy to clipboard operation
later copied to clipboard

Wrong value for next()

Open skilledDeveloper opened this issue 10 years ago • 8 comments

Here is a simple scenario:

var s = later.parse.cron("0 0/15 * * * *", true); //every 15 minutes var date = later.schedule(s).next(1, Date.parse("2014-10-14T03:15:00.999Z")); //2014-10-14T03:15:00.999Z

After (or even at) 03:15:00, the next function should return ‌2014-10-14T03:30:00.999Z but it returns 2014-10-14T03:15:00.999Z instead.

skilledDeveloper avatar Oct 14 '14 03:10 skilledDeveloper

This is a common question, next will return the start date if it meets all of the constraints. This is to ensure that a valid instance is not inadvertently skipped due to timing issues. You can either use nextRange to find the first invalid date to use as the start date or use next(2, startDate) and skip the first result if it is equal to the start date.

bunkat avatar Oct 14 '14 06:10 bunkat

Thanks for the comment. I can fix this by adding an extra second to the startDate. However, I believe next() must return the "next" occurrence when the current occurrence has passed. 03:30:00.999 is almost one second after 03:30:00.000. Why should it return the same time when it's already passed?

skilledDeveloper avatar Oct 14 '14 16:10 skilledDeveloper

Later doesn't know anything about time (oddly enough) and has no idea about the relationship between 03:30:00.999 and 03:30:00.000. All it knows is whether or not a particular date meets all of the constraints that you've specified.

In your case, you've specified that minute values of 0, 15, 30, and 45 should be considered valid (every 15 minutes). Later then checks the first possible date which is the start date to see if it meets all of the constraints. Since the minute value is equal to 30, the date is considered valid and is returned.

bunkat avatar Oct 14 '14 17:10 bunkat

@bunkat you should compare the dates by subtracting them to see whether the time given is after the retrieved one, because I have this issue too and it's across multiple hours.

ilanbiala avatar Jan 24 '15 01:01 ilanbiala

Hello,

Looking at the Later documentation (http://bunkat.github.io/later/parsers.html), it says:

// fires on first second of Jan, Apr, July, Oct
later.parse.recur().every(3).month();

If I have understood correctly what was said before, if a next request starts on a month that is January, April, July or October, the start date will be the first next date, no matter it points or not to the first second of the month.

Is that correct?

gautaz avatar Nov 13 '15 07:11 gautaz

That's correct.

bunkat avatar Nov 13 '15 22:11 bunkat

OK, that's fine as long as it is predictable.

So for the record, I have come up with the following way in order to find the next occurrence after a date:

let schedule = later.schedule(/*a later schedule description*/);
let date = /*a javascript date*/;
let previousOccurrence = schedule.prev(1, date);
let nextOccurrence = schedule.next(2, previousOccurrence)[1];
/* nextOccurrence can be undefined */

Later seems to operate quite well with this but if there is a better way to obtain the next occurrence, please let me know.

Perhaps this could be added to the documentation in the section Calculating instances?

gautaz avatar Nov 15 '15 14:11 gautaz

I also got to this first prev and second next workaround. :-)

mitar avatar Feb 20 '17 09:02 mitar