dmfs/lib-recur

Make RFC5545_LAX lax enough for GCal

lightbody opened this issue · 2 comments

I'm finding that RFC5545_LAX isn't lax enough for some of the data I'm seeing come out of GCal. For example, my software just bumped into an event that had the following:

  • RRULE:FREQ=WEEKLY;WKST=SU;UNTIL=20191226;BYDAY=TH
  • Start: 2019-09-05 08:30 -07:00

This is enough to cause lib-recur to barf, even in lax mode, with the following error:

using allday start times with non-allday until values (and vice versa) is not allowed

Most all other data I see has an RRULE with a date + time for the UNTIL if the event is indeed at a specific time. But clearly this can happen sometimes "in the wild" and it'd be awesome if lib-recur would relax enough to work around it.

Thanks!

dmfs commented

Ha, I've just fixed a similar issue in OpenTasks: https://github.com/dmfs/opentasks/pull/853/files#diff-78b1e6e5c87839a44a6febff094f168aR58

In order to handle this gracefully, we'd either have to convert the absolute time into a floating time or anchor the floating time in a specific time zone. I'll check if and how we would do this in lib-recur.

Ah nice... your approach of changing the rule I think is better. I tried doing this (because I didn't realize changing the rule was possible ha!):

    private org.dmfs.rfc5545.DateTime _hackStart(org.dmfs.rfc5545.DateTime start, RecurrenceRule rule) {
        org.dmfs.rfc5545.DateTime until = rule.getUntil();
        if (until == null) {
            return start;
        }

        if (until.isAllDay() != start.isAllDay()) {
            if (until.isAllDay()) {
                return start.toAllDay();
            } else {
                return start.startOfDay();
            }
        }

        if (until.isFloating() != start.isFloating()) {
            if (until.isFloating()) {
                return start.startOfDay();
            } else {
                return start.toAllDay();
            }
        }

        return start;
    }

And that turned out to be problematic for my use case because it was truncating the time window to the start of the day and effectively causing my to think the next recurring meeting was a day later than it really was (well... 0-23 hours later).

For other reasons I may end up not needing this code / capability at all, but that's really just because I'm finding the Google Calendar API to be incredibly opaque and confusing when it comes to recurring instances so I've resorted to an ugly brute-force that fetches +/-14 days of recurring instances every night at midnight =P

Either way, thanks for creating this project. I'm using it in other parts of my code and it's been tremendously valuable!