cron-parser icon indicating copy to clipboard operation
cron-parser copied to clipboard

prev() wrongly skipping back an extra day on first call in specific case of time change

Open ellis opened this issue 8 months ago • 2 comments

Here is sample code for v5.1.1 that demonstrates the skipped day:

import { CronExpressionParser } from 'cron-parser';
var interval = CronExpressionParser.parse("0 2 * * *", {tz: "America/New_York", currentDate: "2020-03-08T03:01:00.000-04:00"});
console.log(interval.prev().toISOString())
// 2020-03-07T07:00:00.000Z - ERROR: should be 2020-03-08T07:00:00.000Z
console.log(interval.next().toISOString())
// 2020-03-08T07:00:00.000Z

Here is another example where the error is even clearer:

import { CronExpressionParser } from 'cron-parser';
const interval = CronExpressionParser.parse("0 2 * * *", {tz: "America/New_York", currentDate: "2020-03-08T03:01:00.000-04:00"});
console.log(interval.next().toISOString())
// 2020-03-09T06:00:00.000Z
console.log(interval.prev().toISOString())
// 2020-03-07T07:00:00.000Z - ERROR: should be 2020-03-08T07:00:00.000Z

The equivalent code had previously worked in 4.9.0; my unit tests caught the error after I upgraded cron-parser today.

ellis avatar May 08 '25 09:05 ellis

Hi @ellis!

Thanks for reporting this. Strangely enough, v4.9.0 and the latest master (also tested with the initial v5.0.0 release) produce the same faulty result for me.

import { CronExpressionParser } from './src';
import cronParser from './benchmarks/versions/4.9.0/node_modules/cron-parser';

const interval = CronExpressionParser.parse('0 2 * * *', {
  tz: 'America/New_York',
  currentDate: '2020-03-08T03:01:00.000-04:00',
});
console.log(interval.next().toISOString());
console.log(interval.prev().toISOString());

// 2020-03-09T06:00:00.000Z
// 2020-03-07T07:00:00.000Z

const interval2 = cronParser.parseExpression('0 2 * * *', {
  tz: 'America/New_York',
  currentDate: '2020-03-08T03:01:00.000-04:00',
});
console.log(interval2.next().toISOString());
console.log(interval2.prev().toISOString());

// 2020-03-09T06:00:00.000Z
// 2020-03-07T07:00:00.000Z

However, this behavior is rather bizarre and unexpected. I have a feeling it might be related to issue #273, as the current problem also appears to involve DST.

Going to investigate this soon.

Best regards

harrisiirak avatar May 08 '25 12:05 harrisiirak

Same issue here

import * as cronParser from 'cron-parser';

const exp = cronParser.CronExpressionParser.parse('*/5 12-23 * * *');

let i = 0;
while (++i < 20) {
  console.log(exp.next().toDate().toISOString());
  exp.next();
  exp.prev();
}

which outputs:

2025-07-25T06:45:00.000Z
2025-07-25T06:50:00.000Z
2025-07-25T06:55:00.000Z
2025-07-25T07:00:00.000Z
2025-07-25T08:00:00.000Z   <- incorrect
2025-07-25T09:00:00.000Z   <- incorrect
2025-07-25T10:00:00.000Z   <- incorrect
2025-07-25T11:00:00.000Z   <- incorrect
2025-07-25T12:00:00.000Z   <- incorrect
2025-07-25T13:00:00.000Z   <- incorrect
...

geekact avatar Jul 25 '25 06:07 geekact