Hello!

>From http://bugs.meego.com/show_bug.cgi?id=11241. Problem summary below,
patch attached. I'm a bit unsure about hard-coding UTC as time context
in that code, please suggest how this might be improved.

-----------------------------------------

This was sent to us by the phone:

BEGIN:VCALENDAR
VERSION:1.0
TZ:+01
DAYLIGHT:TRUE;+02;20100328T010000Z;20101031T010000Z;;
DAYLIGHT:TRUE;+02;20110327T010000Z;20111030T010000Z;;
BEGIN:VEVENT
SUMMARY:Phone
DTSTART:20101212T090000Z
DTEND:20101212T090000Z
CLASS:PRIVATE
RRULE:D1 20111231T100000
AALARM;TYPE=X-EPOCSOUND:20101212T084500Z;;;
LAST-MODIFIED:20101213T081626Z
PRIORITY:2
END:VEVENT
END:VCALENDAR

Translated into:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Synthesis AG//NONSGML SyncML Engine V3.4.0.8//EN
BEGIN:VTIMEZONE
TZID:Europe/Zurich
BEGIN:STANDARD
DTSTART:19671029T030000
RRULE:FREQ=MONTHLY;INTERVAL=12;BYDAY=-1SU
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:CET
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19870329T020000
RRULE:FREQ=MONTHLY;INTERVAL=12;BYDAY=-1SU
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:CEST
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
LAST-MODIFIED:20101213T081626Z
CLASS:PRIVATE
PRIORITY:2
SUMMARY:Phone
DESCRIPTION:Phone
DTSTART;TZID=Europe/Zurich:20101212T100000
RRULE:FREQ=DAILY;INTERVAL=1;UNTIL=20111231T100000
DTEND;TZID=Europe/Zurich:20101212T100000
BEGIN:VALARM
TRIGGER;VALUE=DATE-TIME:20101212T084500Z
ACTION:DISPLAY
END:VALARM
END:VEVENT
END:VCALENDAR

After changing the summary, it is sent back to the phone as an update as:

BEGIN:VCALENDAR
VERSION:1.0
TZ:+01:00
DAYLIGHT;ENCODING=QUOTED-PRINTABLE:TRUE;+02;20110327T010000Z;20111=
030T010000Z;CET;CEST
BEGIN:VEVENT
LAST-MODIFIED:20101213T091201Z
CLASS:PRIVATE
PRIORITY:2
SUMMARY:Phone mod
DESCRIPTION:Phone
DTSTART:20101212T090000Z
RRULE:D1 20111231
DTEND:20101212T090000Z
AALARM:20101212T084500Z;;;Phone mod
DALARM:20101212T084500Z;;;Phone mod
END:VEVENT
END:VCALENDAR

One relevant difference might be the explicit time in the RRULE. The phone
includes it, the Synthesis engine doesn't. Yep, that seems to be it. Both
"forever" (RRULE:D1 #0) and "fixed number of times" work. The later one works
because the Synthesis engine internally converts it into a fixed end date/time.

The spec says that the end date must contain a time:

enddate::= ISO 8601_date_time value(e.g., 19940712T101530Z)

It does not say whether that end datetime is included in the recurrence, but
experiments show that this is the interpretation on the phone (vCalendar 1.0)
and in Evolution (iCalendar 2.0).

Given that vCalendar does not allow floating end dates, I think the encoder for
vCalendar RRULE should be fixed to not generate such broken rules. What time it
should insert as fallback might be a bit tricky, but I think the start time of
the event should do.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.

>From 400b471a43d02dbcdf2c6affdde7ac1b1d7171a8 Mon Sep 17 00:00:00 2001
From: Patrick Ohly <patrick.o...@intel.com>
Date: Mon, 13 Dec 2010 13:08:40 +0100
Subject: [PATCH] vCalendar 1.0: avoid RRULE end date without time

When parsing an iCalendar 2.0 event, it is possible to arrive at
an rrule "until" date/time which contains no time value. vCalendar 1.0
requires such a time. Not sending it, as the engine did before, causes
Nokia phones to ignore the recurrence rule (bugs.meego.com #11241).

This patch avoids this case by looking at the time of the event start
and adds that time to the recurrence until date. The comment in the
default config says:
      <!-- recurrence rule block, fields must be in that order, including
           DTSTART as last field !! -->

But it doesn't seem like DTSTART was really used before. Therefore this
patch tries to deal with not finding a timestamp after the recurrence rule
block by clearing the TCTX_DATEONLY, without actually setting a time. Probably
not quite correct, but perhaps better than not changing anything.

Another problematic aspect is to match the time zone context of the
"until" clause with the "start" date/time of the event. Currently the patch
assumes that the start time is going to be encoded as UTC.
---
 src/sysync/mimedirprofile.cpp |   30 ++++++++++++++++++++++++++++++
 1 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/src/sysync/mimedirprofile.cpp b/src/sysync/mimedirprofile.cpp
index 2cbce65..1314240 100644
--- a/src/sysync/mimedirprofile.cpp
+++ b/src/sysync/mimedirprofile.cpp
@@ -1700,6 +1700,12 @@ bool TMimeDirProfileHandler::fieldToMIMEString(
       // - until
       if (!(tsFldP = ITEMFIELD_DYNAMIC_CAST_PTR(TTimestampField,fty_timestamp,aItem.getArrayField(aFid,aArrIndex,true)))) return false;
       aFid++; // do NOT INCREMENT in macro, as it would get incremented twice
+      // - start time (according to comment for "recurrence rule block", this must
+      // follow the rule block, but wasn't used before, so let's be conservative
+      // and do not throw an error when we don't find a time stamp there)
+      TTimestampField *tsStartTime;
+      tsStartTime = ITEMFIELD_DYNAMIC_CAST_PTR(TTimestampField,fty_timestamp,aItem.getArrayField(aFid,aArrIndex,true));
+      aFid++; // do NOT INCREMENT in macro, as it would get incremented twice
       // Until
       // - UTC preferred as output format if basically possible and not actively disabled
       untilcontext=
@@ -1716,6 +1722,30 @@ bool TMimeDirProfileHandler::fieldToMIMEString(
       // Now do the conversion
       bool ok;
       if (fMimeDirMode==mimo_old) {
+        // cannot encode rrule with an end date which has no time
+        if (TCTX_IS_DATEONLY(untilcontext)) {
+          // add real start time, if possible;
+          // if not, then encoding whatever time is in
+          // "until" is still better than not generating a time
+          // component in the RRULE
+          if (tsStartTime) {
+            // strip time (if any) from "until" and combine it with
+            // time from event "starttime", using UTC
+            // TODO: what if the device does not support UTC?
+            lineartime_t starttime = tsStartTime->getTimestampAs(TCTX_UTC);
+            sInt16 year, month, day, hour, min, sec, ms;
+            lineartime2date(until, &year, &month, &day);
+            lineartime2time(starttime, &hour, &min, &sec, &ms);
+            until = date2lineartime(year, month, day) +
+              time2lineartime(hour, min, sec, ms);
+            untilcontext = TCTX_UTC;
+            PDEBUGPRINTFX(DBG_GEN+DBG_EXOTIC,("combined until date and start time into new end date/time"));
+          } else {
+            untilcontext &= ~TCTX_DATEONLY;
+            PDEBUGPRINTFX(DBG_ERROR,("Warning: creating vCalendar 1.0 RRULE with unspecified end time, need start time of recurring event after recurrence rule block"));
+          }
+        }
+
         // vCalendar 1.0 type RRULE
         ok = internalToRRULE1(
           aString,
-- 
1.7.2.3

_______________________________________________
os-libsynthesis mailing list
os-libsynthesis@synthesis.ch
http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis

Reply via email to