Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iCal library to iterate recurring events with specific instances [closed]

I'm looking for a library (preferably Python, but the language doesn't matter much) that is able to iterate recurring iCal events and handles specific instances automatically.

The iCal file that I'm working with contains recurring events (for example: RRULE:FREQ=WEEKLY;UNTIL=20150614;BYDAY=MO,TU,WE,TH,FR). These recurring events sometimes have specific instances: the summary might be changed for a single event, or one event is deleted. This result in VEVENTs in the iCal file with properties like RECURRENCE-ID and EXDATE.

Most iCal libraries that I've looked (python-icalendar, ical.js, php iCalCreator) at will help you with the parsing, but will simply return separate (and non-grouped) VEVENTs for all specific instances. This means you will have to match them to the relevant RRULE yourself and also determine how this influences the RRULE.

So, lets assume a recurring event that happens on Monday-Friday from 9:00-10:00. But with a specific instance on Friday (10:00-11:00) and a deleted instance on Wednesday. In this case I would like to iterate the events in a fashion like this:

[
  {start: '2015-06-15 09:00:00', end: '2015-06-15 10:00:00'},
  {start: '2015-06-16 09:00:00', end: '2015-06-16 10:00:00'},
  {start: '2015-06-18 09:00:00', end: '2015-06-18 10:00:00'},
  {start: '2015-06-19 10:00:00', end: '2015-06-19 11:00:00'},
]
like image 918
Intru Avatar asked Nov 09 '22 11:11

Intru


1 Answers

The Python library recurring-ical-events unfolds events with repetition according the the RFC5455.

pip install recurring-ical-events

Example:

import icalendar
import datetime
import recurring_ical_events
import urllib.request

start_date = (2019, 3, 5)
end_date =   (2019, 4, 1)
url = "https://raw.githubusercontent.com/niccokunzmann/python-recurring-ical-events/master/test/calendars/recurring-events-changed-duration.ics"

ical_string = urllib.request.urlopen(url).read()
calendar = icalendar.Calendar.from_ical(ical_string)
events = recurring_ical_events.of(calendar).between(start_date, end_date)
for event in events:
    start = event["DTSTART"].dt
    duration = event["DTEND"].dt - event["DTSTART"].dt
    print("start {} duration {}".format(start, duration))

Output:

start 2019-03-18 04:00:00+01:00 duration 1:00:00
start 2019-03-20 04:00:00+01:00 duration 1:00:00
start 2019-03-19 04:00:00+01:00 duration 1:00:00
start 2019-03-07 02:00:00+01:00 duration 1:00:00
start 2019-03-08 01:00:00+01:00 duration 2:00:00
start 2019-03-09 03:00:00+01:00 duration 0:30:00
start 2019-03-10 duration 1 day, 0:00:00

Old Answer:

From the answer of Sven,

dateutil.rrule claims to handle the rules from ICalendar RFC 5545. If you have a look at the examples, it provides datetime objects.

like image 135
User Avatar answered Nov 14 '22 21:11

User