ical.net icon indicating copy to clipboard operation
ical.net copied to clipboard

How to get repeating occurences from RRULE strin

Open pantonis opened this issue 5 years ago • 5 comments

I have not found a single tutorial of how to parse an RRULE string and get the occurences. Is this not supported by this library?

pantonis avatar Apr 06 '20 08:04 pantonis

I'm curious as well. @pantonis Any luck in your search?

elamje avatar Jun 01 '20 19:06 elamje

You can use this library to get occurrences. But if you want all the occurrences, well, that's not really a complete possibility.

  • Creating a new RecurrencePattern based on the RRULE string
  • Adding that pattern to a new CalendarEvent - so that we have the start and end time for when the recurrences take place
  • Calling GetOccurrences on the calendar event object, passing in the date range you wish to calculate the occurrences for.

This seems fairly reasonable, since indefinite recurrences would mean you'd never actually get a finite answer to an occurrences inquiry. If you really needed to, I suppose you could set the end date on GetOccurrences to some date far in the future (note: DateTime.Max did not work for me when I tested this). For example, perhaps you could say your end date range is Today's date plus 10 years.

As others have pointed out, the purpose of RRULE in the iCalendar spec is to consolidate recurrences. Not to expand them out (and certainly not for indefinite ones). If your RRULE has Until specified, that gives you an easy way to pull your end parameter for GetOccurrences.

The only tricky one that jumps out at me is when an RRULE uses just Count. In these cases, I'd suggest using an arbitrary date in the somewhat-distant-but-not-too-distant-future.

vanpyrzericj avatar Jun 01 '20 23:06 vanpyrzericj

@elamje I have found out some things but the library in general behaves very strange. I have an example that I have quarterly events start date 01/07/2020, end date 30/09/202 with rrule RRULE:FREQ=MONTHLY;INTERVAL=3 and it returns back some correct occurences but also some wrong ones. I get 01/01/2021 - 02/04/2021 where as end date should be 31/03/2021

pantonis avatar Jun 02 '20 10:06 pantonis

@elamje here is a snippet that I am using to get repeating occurrences

 public void GetRecurrences()
        {
            string rrule = "RRULE:FREQ=MONTHLY;INTERVAL=3";
            if (string.IsNullOrWhiteSpace(rrule))
                return;

            var dtStart = new DateTime(2020, 4, 1);
            var dtEnd = new DateTime(2020, 6, 30);

            RecurrencePattern recurrenceRule = new RecurrencePattern(rrule);
            var vEvent = new CalendarEvent
            {
                DtStart = new CalDateTime(dtStart),
                DtEnd = new CalDateTime(dtEnd),
                RecurrenceRules = new List<RecurrencePattern> { recurrenceRule },
            };

            var calendar = new Calendar();
            calendar.Events.Add(vEvent);

            var startSearch = new CalDateTime(dtStart.AddDays(-1));

            var endSearch = new CalDateTime(DateTime.UtcNow.AddYears(30));
            HashSet<Occurrence> occurrences = calendar.GetOccurrences(startSearch, endSearch);

            foreach (var item in occurrences)
            {
                Console.WriteLine($"{item.Period.StartTime} - {item.Period.EndTime}");
            }
        }

pantonis avatar Jun 03 '20 05:06 pantonis

Should it work if the RRULE string contains DTSTART and DTEND? They seem to be ignored in my test when using this RRULE:

DTSTART:20200101T150000Z
DTEND:20200101T160000Z
RRULE:FREQ=DAILY;COUNT=10;INTERVAL=5

iamkinetic avatar Jun 11 '20 14:06 iamkinetic