Add new calendar from ics-file and continously update it with script?

Thanks for clarifying.

When fetching the calendar from Nextcloud with CalDAV with the above mentioned script recurring events are grouped with the exceptions (verified by printing the serialized event). Am I correct that a sabre vovject/vevent is used? To me it seems that this is the reason why all exceptions are considered to be new events.

I wonder if it is possible to extract the exceptions and process them as separate events. As I dont’t know much about the data structures any tip would be appreciated.

It seems there is an option to accomplish that with the ICSExportPluging from sabredav (see Line 28):

1 Like

I just wanted to start to test this, but after carefully reading the comment and the code I got to the conclusion that “expand” means to expand the entire RRULE into individual events for every occurence. As the timezone is stripped there is no other possibility.

The problem is that the ICS file I want to import has (among others) one main VEVENT with an RRULE with some exclusions per EXDATE and e.g. 20 VEVENTS that specify exceptions (changed location, time, …) for individual occurences of the main event as one VEVENT per exception with an include RECURRENCE-ID.

Thank you too! Thanks for also reporting your problems. The library I use vor CalDAV access seems to do quite less error checking.
I just released version 0.3.2 of my script that adds some basic error checking on the CalDAV URL and can warn the user about wrong credentials and wrong calendar URL / ID - so next user will have it a bit easier.

Regarding recurring events: I’m not sure if they are handled correctly, and I don’t know how to do it correctly, I’m sorry.
I’m glad that the ICS file I’m using doesn’t contain recurring events, so that’s something I didn’t dig into. I’ll sure be glad to accept a pull request if you can make may script support that too.

I am currently testing a modified version which seems to handle recurring events just fine. For CalDAV a calendar consists of calendar objects. Each calendar object contains one or multiple events with the same UID all belonging to one recurring event.

When reading the ICS file the parser generates individual events and not calendar objects. But there exists a splitter that can group individual events to calendar objects.

Instead of using

$vcalendar = VObject\Reader::read(fopen($config[‘ICS’][‘url’], ‘r’), VObject\Reader::OPTION_FORGIVING);

I am using

$splitter = new ICalendar(fopen($config[‘ICS’][‘url’], ‘r’), VObject\Reader::OPTION_FORGIVING);


while ($vObject = $splitter->getNext())


As recurring events have many options I also changed the hashing from using explicitly specified elements to just calculating the hash of $vobject->serialize(). This also works flawlessly for recurring events with many exceptions. The only problem perhaps caused by Outlook (which I use for exporting the ICS file) is the DTSTAMP field which changes quite often for a quite high number of events. This field only seems to be important for synchronisation and responses to invitations but for just importing I can imagine no real use case. So I changed it to a dummy value before hashing and importing. Now only really changed events are deleted and recreated with the new data.

Another problem caused by Outlook is Exceptions to recurring events that did not repeat some properties, e.g. the SUMMARY etc. In Nextcloud this lead to events without a title. So I had to copy missing (important) properties from the main event to the exceptions.

Of course I would like to show the resulting code, but currently it’s a big mess because it was mainly a trial and error process as I am not used to PHP :upside_down_face. But as it seems to be working I will try to create a pull request, but that will certainly take some days.