This is such a nightmare, but that’s ok, because it’s a subset of the larger CalDAV nightmare. (Inconsistent formats, inconsistent standards implementations, etc.) In kcaldav, I ended up parsing and ignoring rrules, and just fetching all entries on collection requests because computing recurrences within intervals is complicated. Let the client sort it out.
Whenever I get back to this (unfortunately, “it just works” for my tiny calendar, which is the enemy of “make it work better”), I’ve scratched the surface (in datetime.c) with a way to bisect recurring intervals from a rule until on falls within a duration, and simply bound durations below to, say, the daily or hourly level. Either way, I’d need to pull ever rrule from the database and run this routine.
If you’re interested in dirtying your hands with CalDAV, it’s all there, but certainly not easy.