jens-maus / node-ical

NodeJS class for parsing iCalendar/ICS files
Apache License 2.0
122 stars 52 forks source link

Event date and recurrence dates out of sync #212

Open axtg opened 2 years ago

axtg commented 2 years ago

I've been looking through the rrule repo for this as well, but so far haven't figured out where the discrepancy comes from that I am encountering. I have the following ics:

DTSTART;TZID=Europe/Amsterdam:20220622T190000
DTEND;TZID=Europe/Amsterdam:20220622T193000
RRULE:FREQ=DAILY;UNTIL=20220624T215959Z

event.start.utc() gives me 17 for the hour (true), while event.rrule.all()[0].getUTCHours() gives me 15. The former is correct. It seems somehow that the rule UTC offset is applies twice? Could that be?

Tldr; example RRule from docs ### [Example code from the docs](https://github.com/jens-maus/node-ical#recurrence-rule-rrule) ```js const dates = event.rrule.between(new Date(2022, 0, 1, 0, 0, 0, 0), new Date(2022, 11, 31, 0, 0, 0, 0)) if (dates.length === 0) continue; console.log('Summary:', event.summary); console.log('Original start:', event.start); console.log('RRule start:', `${event.rrule.origOptions.dtstart} [${event.rrule.origOptions.tzid}]`) dates.forEach(date => { let newDate if (event.rrule.origOptions.tzid) { // tzid present (calculate offset from recurrence start) const dateTimezone = moment.tz.zone('UTC') const localTimezone = moment.tz.guess() const tz = event.rrule.origOptions.tzid === localTimezone ? event.rrule.origOptions.tzid : localTimezone const timezone = moment.tz.zone(tz) const offset = timezone.utcOffset(date) - dateTimezone.utcOffset(date) newDate = moment(date).add(offset, 'minutes').toDate() } else { // tzid not present (calculate offset from original start) newDate = new Date(date.setHours(date.getHours() - ((event.start.getTimezoneOffset() - date.getTimezoneOffset()) / 60))) } const start = moment(newDate) console.log('Recurrence start:', start) }) ``` ### Result Here you see that the Original start and UTC RRule start are 22 June 17:00:00, yet the three recurrences start at 15:00:00 UTC. ``` 2022-08-20T12:50:28.775Z f63d18df-c840-418e-9389-8731a38f7b73 INFO Summary: Test recurring end date 2022-08-20T12:50:28.776Z f63d18df-c840-418e-9389-8731a38f7b73 INFO Original start: 2022-06-22T17:00:00.000Z { tz: 'Europe/Amsterdam' } 2022-08-20T12:50:28.777Z f63d18df-c840-418e-9389-8731a38f7b73 INFO RRule start: Wed Jun 22 2022 17:00:00 GMT+0000 (Coordinated Universal Time) [Europe/Amsterdam] 2022-08-20T12:50:29.137Z f63d18df-c840-418e-9389-8731a38f7b73 INFO Recurrence start: Moment<2022-06-22T15:00:00+00:00> 2022-08-20T12:50:29.137Z f63d18df-c840-418e-9389-8731a38f7b73 INFO Recurrence start: Moment<2022-06-23T15:00:00+00:00> 2022-08-20T12:50:29.137Z f63d18df-c840-418e-9389-8731a38f7b73 INFO Recurrence start: Moment<2022-06-24T15:00:00+00:00> ``` ### Dump of `event.rrule` ``` 2022-08-20T13:02:53.732Z 12a40880-be48-4393-ac31-28142c3eb329 INFO RRule { _cache: Cache { all: [ 2022-06-22T15:00:00.000Z, 2022-06-23T15:00:00.000Z, 2022-06-24T15:00:00.000Z ], before: [], after: [], between: [] }, origOptions: { tzid: 'Europe/Amsterdam', dtstart: 2022-06-22T17:00:00.000Z, freq: 3, until: 2022-06-24T21:59:59.000Z }, options: { freq: 3, dtstart: 2022-06-22T17:00:00.000Z, interval: 1, wkst: 0, count: null, until: 2022-06-24T21:59:59.000Z, tzid: 'Europe/Amsterdam', bysetpos: null, bymonth: null, bymonthday: [], bynmonthday: [], byyearday: null, byweekno: null, byweekday: null, bynweekday: null, byhour: [ 17 ], byminute: [ 0 ], bysecond: [ 0 ], byeaster: null } } ```
sdetweil commented 1 year ago

no.. RRULE expects NON-TZ based dates.. and gets confused..

see https://github.com/jens-maus/node-ical/issues/260#issuecomment-1515339667