Thanks!
RDATE: missing first instance and time zone ignored
-
Hi,
Davdroid ignores the time zone information in an RDATE. Also it ignores the DTSTART as the first event date. Example:
VERSION:2.0 PRODID:-//Radicale//NONSGML Radicale Server//EN BEGIN:VTIMEZONE TZID:Europe/Berlin BEGIN:STANDARD DTSTART:20001029T030000 RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 TZNAME:CET TZOFFSETFROM:+0200 TZOFFSETTO:+0100 END:STANDARD BEGIN:DAYLIGHT DTSTART:20000326T020000 RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3 TZNAME:CEST TZOFFSETFROM:+0100 TZOFFSETTO:+0200 END:DAYLIGHT END:VTIMEZONE BEGIN:VEVENT UID:1:-191507020323643003 DTSTART;TZID=Europe/Berlin:20141015T160000 DTEND;TZID=Europe/Berlin:20141015T160000 RDATE;TZID=Europe/Berlin:20141022T160000,20141029T160000,20141105T160000 SUMMARY:Test BEGIN:VALARM ACTION:DISPLAY DESCRIPTION:Test TRIGGER:-PT10M END:VALARM END:VEVENT END:VCALENDAR
-
For RDATE time zones, there isn’t even a column that could be synchronized: http://developer.android.com/reference/android/provider/CalendarContract.EventsColumns.html
DAVdroid can only synchronize between the CalDAV server and the Android Calendar provider but not define columns on its own. So I guess this is an Android limitation?
For the other thing with the DTSTART, I’ll have a look. What exactly do you mean by “ignores the DTSTART as the first event date”?
Also, information about your setup (including Android flavour and version) would be very useful, please see here.
-
- rfc2822 notifications@github.com [2014-10-22 15:46]:
For RDATE time zones, there isn’t even a column that could be synchronized: http://developer.android.com/reference/android/provider/CalendarContract.EventsColumns.html
DAVdroid can only synchronize between the CalDAV server and the Android Calendar provider but not define columns on its own. So I guess this is an Android limitation?
I had a quick look and I think you can simply put the complete RDATE
string into the database:conjunction with RRULE to define an aggregate set of repeating occurrences. For more discussion, see the RFC5545 spec.
(http://developer.android.com/guide/topics/providers/calendar-provider.html#events)
Also have a look into line 264 of
https://android.googlesource.com/platform/packages/providers/CalendarProvider/+/master/src/com/android/providers/calendar/CalendarInstancesHelper.java
where an RecurrenceSet is instantiated:
https://android.googlesource.com/platform/frameworks/opt/calendar/+/06b3293d5af3454a39681cfd659271551354b8a0/src/com/android/calendarcommon2/RecurrenceSet.java
which has code to parse the time zone information.I didn’t tried it though ;).
For the other thing with the DTSTART, I’ll have a look. What exactly do you mean by “ignores the DTSTART as the first event date”?
The example above has a DTSTART date that not included in the RDATE
DTSTART;TZID=Europe/Berlin:20141015T160000
. This is not shown in
the Android calendar, but in others like Sunbird.Also, information about your setup (including Android flavour and version) would be very useful, please see here.
- DAVdroid 0.6.3 from F-Droid
- Samsung Galaxy S2G running Android 4.4.4 (OmniRom 4.4.4-20141006-i9100g-HOMEMADE)
-
In https://android.googlesource.com/platform/frameworks/opt/calendar/+/06b3293d5af3454a39681cfd659271551354b8a0/src/com/android/calendarcommon2/RecurrenceSet.java line 143 you can see:
int tzidx = recurrence.indexOf(";"); if (tzidx != -1) { tz = recurrence.substring(0, tzidx); recurrence = recurrence.substring(tzidx + 1); }
So, the
rdateStr
(taken from the database, i.e. passed by DAVdroid) seems to be expected in this format:Europe/Berlin;date1,date2
However, DAVdroid passes what iCal4j returns (
TZID=Europe/Berlin:date1,date2
).So it seems that the RDate string can’t be passed 1:1 into the database as the docs say. Do you agree?
Also [DAVdroid] ignores the DTSTART as the first event date.
I have confirmed that for the given VEVENT, the start event doesn’t appear in the calendar as soon as RDATE is set. However, DAVdroid clearly adds the event to the database (as it’s only one row and the recurrence dates appear in the calendar). The only difference is that in the latter case, it sets DURATION=PT0S instead of a DTEND as required by the docs.
Note that when using RRULE instead of RDATE, the DTSTART event is shown. So I guess that this may be an Android issue, too.
Open for further investigation. Help is appreciated.
-
Also it ignores the DTSTART as the first event date.
At least this problem is also present for CalDAV-Sync from Marten Gajda. So I guess it’s really an Android problem.
-
- rfc2822 notifications@github.com [2014-11-12 06:21]:
So it seems that the RDate string can’t be passed 1:1 into the database as the docs say. Do you agree?
Yes, I guess you have to replace ‘:’ by ‘;’.
I have confirmed that for the given VEVENT, the start event doesn’t appear in the calendar as soon as RDATE is set. However, DAVdroid clearly adds the event to the database (as it’s only one row and the recurrence dates appear in the calendar). The only difference is that in the latter case, it sets DURATION=PT0S instead of a DTEND as required by the docs.
What about adding DTSTART to the RDATE set?
-
Yes, I guess you have to replace ‘:’ by ‘;’.
Hm, I guess Android people would replace “;” by “:” instead? Or at least change the docs. If this can be confirmed, I’d even provide a patch for AOSP.
What about adding DTSTART to the RDATE set?
I’d do that if that requirement was documented in the Android docs. I’d prefer to locate the actual problem (and why it doesn’t occur with RRULE) and provide a fix for AOSP.
-
Adding a patch to AOSP sounds good as well, the other ideas could be
helpful to be backward compatible. -
- Regarding the time zones: DAVdroid now writes the TZID (if set) to the Calendar provider, causing the recurring instances to have correct time. The time zone are not shown in the calendar due Android recurrence processing, but the time should be correct.
- Regarding the missing first instance: Android’s RecurrenceProcessor method expand() is responsible for expanding the recurrence. It’s called with both DTSTART and RDATE, but it only returns the RDATE recurrences. CalendarInstancesHelper takes
- DTSTART in case of non-recurring events,
- the result of
RecurrenceProcessor.expand(DTSTART,RDATE)
(which does not include the DTSTART instance) in case of recurring events
as the instance date(s), so it misses the DTSTART instance in case of recurring events.
So I consider this an Android bug; I guess it’s caused by a non-precise specification of whether``RecurrenceProcessor.expand(DTSTART,RDATE)
shall return the first instance or not. Because of this missing specification, wrong assumptions are made in
CalendarInstancesHelper`, causing this bug. -
Please also follow up at https://code.google.com/p/android/issues/detail?id=171292
-
As the time zone issue has been fixed in DAVdroid, I’ll consider this issue as a third-party bug from now on.
-
Hi rfc2822, thanks for taking care of this!
-
Let’s see whether this issue will be fixed in Android.
-
For reference, I’ve worked around these two here: https://github.com/jspricke/python-remind/blob/master/remind.py#L165
-
Please see also https://code.google.com/p/android/issues/detail?id=172442