ical.js
ical.js copied to clipboard
Timezone not set correctly when iterating occurrences
ics file:
BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
BEGIN:VEVENT
CREATED:20160728T114557Z
LAST-MODIFIED:20160728T122120Z
DTSTAMP:20160728T122120Z
UID:9fda684c-373b-4f58-9fc7-6db9f06218b5
SUMMARY:Test-Event
RRULE:FREQ=WEEKLY;UNTIL=20160912T080000Z
EXDATE:20160808T080000Z
DTSTART;TZID=Europe/Berlin:20160725T100000
DTEND;TZID=Europe/Berlin:20160725T110000
TRANSP:OPAQUE
SEQUENCE:3
X-MOZ-GENERATION:4
END:VEVENT
BEGIN:VEVENT
CREATED:20160728T115039Z
LAST-MODIFIED:20160728T115048Z
DTSTAMP:20160728T115048Z
UID:9fda684c-373b-4f58-9fc7-6db9f06218b5
SUMMARY:Test-Event - Reccurence #2
RECURRENCE-ID;TZID=Europe/Berlin:20160801T100000
DTSTART;TZID=Europe/Berlin:20160801T100000
DTEND;TZID=Europe/Berlin:20160801T110000
TRANSP:OPAQUE
SEQUENCE:2
X-MOZ-GENERATION:3
END:VEVENT
BEGIN:VEVENT
CREATED:20160728T114921Z
LAST-MODIFIED:20160728T122231Z
DTSTAMP:20160728T122231Z
UID:9fda684c-373b-4f58-9fc7-6db9f06218b5
SUMMARY:Test-Event
TRANSP:OPAQUE
CLASS:PUBLIC
RECURRENCE-ID;TZID=Europe/Berlin:20160725T100000
DTSTART;TZID=Europe/Berlin:20160725T100000
DTEND;TZID=Europe/Berlin:20160725T113000
END:VEVENT
PRODID:-//Inf-IT//InfCloud 0.12.1//EN
END:VCALENDAR
Code:
const ICAL = require("ical.js");
const fs = require('fs');
var buffer = fs.readFileSync("/file.ics", "utf8");
var jcal = ICAL.parse(buffer);
var vcalendar = new ICAL.Component(jcal);
var vevents = vcalendar.getAllSubcomponents('vevent');
var event;
var exceptions = [];
vevents.forEach((vevent, i) => {
let _event = new ICAL.Event(vevent);
if ( _event.isRecurring() ) {
event = _event;
} else if( _event.isRecurrenceException() ) {
exceptions.push(_event);
}
});
if(event) {
exceptions.forEach((ex) => {
event.relateException(ex);
});
var exdates = [];
event.component.getAllProperties('exdate').forEach((exdate) => {
exdates.push(exdate.getFirstValue().toJSDate());
});
let it = event.iterator();
// console.log(it);
var occ;
while((occ = it.next())) {
var details = event.getOccurrenceDetails(occ);
var jsDate = details.startDate.toJSDate();
// console.log(jsDate, exdates.indexOf(jsDate));
/// Does not work due to different objects
// Another problem is the timezone
if(exdates.indexOf(jsDate) != -1) {
console.log(" ", jsDate, 'IGNORED'); // THIS NEVER GETS CALLED
} else {
console.log(" ", jsDate, details.item.summary, event.findRangeException(details.startDate), it.exDate);
}
}
}
it.exDate is undefined after the date that should be excluded, but I still see it through the iterator.
In lib/ical/recur_expansion.js:267 you compare the EXDATE to "last". Last points at the end of the event (10am), but the EXDATE points to the start (8am).
Addition: It looks like a problem with the timezone. The exDate is correctly in timezone 'Z' with utcOffset 0. In contrast, the startDate I get from the iterator for the occurence details object is 10:00:00 with utcOffset 0 and tz 'floating' which is obviously wrong!
Does it work correctly when using UTC as the timezone? I won't have immediate time to look into this. Can you create a minimal testcase I can paste into http://jsfiddle.net/kewisch/227efboL/ ?
I made a wrapper for ical.js that solves this problem: https://github.com/mifi/ical-expander
@mifi Nice thank you. The problem is not easily solved within ical.js since it does not know standard timezones.
It seems that EXDATE is not considered in ical.js at all, I was not even able to find this information in the event properties.
I had to use https://github.com/mifi/ical-expander at the end and it worked like a charm.