jkbrzt / rrule

JavaScript library for working with recurrence rules for calendar dates as defined in the iCalendar RFC and more.
https://jkbrzt.github.io/rrule
Other
3.29k stars 514 forks source link

Infinite loop on rule.between() #481

Open CarloAndreoli1994 opened 2 years ago

CarloAndreoli1994 commented 2 years ago

I'm stucked in an infinite loop caaling the rrule.between(date1, date2) with the following rrule: 2021-09-17T10:56:00.472Z 2021-09-17T09:56:00.472Z 2021-09-18T10:56:00.472Z

const rule = new RRule({
          freq:
            item.recurringType == 'weekly'
              ? RRule.WEEKLY
              : item.recurringType == 'single'
              ? RRule.DAILY
              : RRule.YEARLY,
          interval: item.recurringSeparation,
          byweekday: [newsService.formatRruleWeekday(new Date(item.recurringDate).getDay())],
          dtstart: new Date(item.recurringDate),
          until: '2021-09-18T10:56:00.472Z'
})

console.log(rule):

RRule {
  _cache: Cache { all: false, before: [], after: [], between: [] },
  origOptions: {
    freq: 3,
    interval: null,
    byweekday: [ 1 ],
    dtstart: 2021-09-14T09:00:00.000Z,
    until: 2021-09-18T10:33:00.224Z
  },
  options: {
    freq: 3,
    dtstart: 2021-09-14T09:00:00.000Z,
    interval: null,
    wkst: 0,
    count: null,
    until: 2021-09-18T10:33:00.224Z,
    tzid: null,
    bysetpos: null,
    bymonth: null,
    bymonthday: [],
    bynmonthday: [],
    byyearday: null,
    byweekno: null,
    byweekday: [ 1 ],
    bynweekday: null,
    byhour: [ 9 ],
    byminute: [ 0 ],
    bysecond: [ 0 ],
    byeaster: null
  }
}

Then calling:

rule.between('2021-09-17T09:56:00.472Z', '2021-09-17T10:56:00.472Z').forEach((rule) => {
 .....
})

I get the Infinite loop here on debugging: Screen Shot 2021-09-16 at 16 47 50 PM

Package version: 2.6.8

OS: macOS Big Sur 11.4

theninadoge commented 2 years ago

I've created a PR to fix this, but you can also get around the issue by ensuring your interval is not null/undefined.

const rule = new RRule({
          freq:
            item.recurringType == 'weekly'
              ? RRule.WEEKLY
              : item.recurringType == 'single'
              ? RRule.DAILY
              : RRule.YEARLY,
          interval: item.recurringSeparation || 1,
          byweekday: [newsService.formatRruleWeekday(new Date(item.recurringDate).getDay())],
          dtstart: new Date(item.recurringDate),
          until: '2021-09-18T10:56:00.472Z'
})
theninadoge commented 2 years ago
const rule = new RRule({
  freq: RRule.DAILY,
  interval: 1,
  byweekday: RRule.TU,
  dtstart: new Date('2021-09-14T09:00:00.000Z'),
  until: new Date('2021-09-18T10:56:00.472Z'),
});

console.log(rule);
console.log("between", rule.between(new Date('2021-09-17T09:56:00.472Z'), new Date('2021-09-17T10:56:00.472Z')))

results in

RRule {
  _cache: Cache { all: false, before: [], after: [], between: [] },
  origOptions: {
    freq: 3,
    interval: 1,
    byweekday: Weekday { weekday: 1, n: undefined },
    dtstart: 2021-09-14T09:00:00.000Z,
    until: 2021-09-18T10:56:00.472Z
  },
  options: {
    freq: 3,
    dtstart: 2021-09-14T09:00:00.000Z,
    interval: 1,
    wkst: 0,
    count: null,
    until: 2021-09-18T10:56:00.472Z,
    tzid: null,
    bysetpos: null,
    bymonth: null,
    bymonthday: [],
    bynmonthday: [],
    byyearday: null,
    byweekno: null,
    byweekday: [ 1 ],
    bynweekday: null,
    byhour: [ 9 ],
    byminute: [ 0 ],
    bysecond: [ 0 ],
    byeaster: null
  }
}
between []