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

RRule.fromString() behaves differently than if I inputted the values manually #630

Open SharpieGod opened 1 month ago

SharpieGod commented 1 month ago

fromString() behaves differently

import { DateTime } from "luxon";
import { RRule } from "rrule";

const rrule = RRule.fromString(event.recurrence[0]); // RRULE:FREQ=DAILY

if (!event.start?.dateTime) return null;
const startDateTime = DateTime.fromISO(event.start.dateTime);
console.log(startDateTime.toJSDate());

rrule.options.dtstart = startDateTime.toJSDate(); // 2024-05-01T11:30:00.000Z
rrule.options.tzid = event.start?.timeZone ?? "America/New_York";
const startTime = startDateTime.toJSDate();

rrule.options.bysecond = [startTime.getSeconds()]; // Never mentioned in the docs, works for some reason
rrule.options.byminute = [startTime.getMinutes()]; // If not set defaults to current time (wrong)
rrule.options.byhour = [startTime.getHours()];

const dates = rrule
  .all((d, i) => {
    return i < 1;
  })
  .map((d) => {
    // Removes daylight savings time
    const localOffset = d.getTimezoneOffset();
    return new Date(d.getTime() + localOffset * 60000);
  });

console.log(dates); // [ 2024-05-02T04:30:00.000Z ]

The function (all()) does not return the first correct date, which is the dtstart. Furthermore if the same exact inputs are used to construct an RRule object with the options set, it does return the correct datetime.

const rrule = new RRule({
  dtstart: DateTime.fromISO(event.start?.dateTime ?? "").toJSDate(),
  freq: RRule.DAILY,
});

const dates = rrule.all((d, i) => {
  return i < 1;
});

console.log(dates); // [ 2024-05-01T11:30:00.000Z ] (correct)

Also now there is no need to set the bysecond, byminute, and byhour values

I am trying to integrate my program with google calendar events, and if I am doing something wrong please tell me. Thanks.