(copied from the original discussion on this parser module: http://drupal.org/node/214688#comment-1114385)

The problem I'm having now is with all-day appointments. They are showing up in the Calendar view either on the day after they actually occur, or on both the day they occur and the next day. Here's what is in the ICS file, for example:

BEGIN:VEVENT
UID:84404659-870e-4fa9-a4c7-285810d1065e
SUMMARY:THANKSGIVING DAY
ORGANIZER;SENT-BY="mailto:someone@corporate.com":mailto:corporateevents@corporate.com
X-MS-OLK-SENDER;CN=Someone:mailto:someone@corporate.com
DTSTART;VALUE=DATE:20081127
DTEND;VALUE=DATE:20081128
STATUS:CONFIRMED
CLASS:PUBLIC
X-MICROSOFT-CDO-ALLDAYEVENT:TRUE
X-MICROSOFT-CDO-INTENDEDSTATUS:FREE
TRANSP:OPAQUE
X-MICROSOFT-DISALLOW-COUNTER:TRUE
DTSTAMP:20081105T162136Z
SEQUENCE:0
BEGIN:VALARM
ACTION:DISPLAY
TRIGGER;RELATED=START:-PT1080M
DESCRIPTION:Reminder
END:VALARM
END:VEVENT

So I see the end date is indeed the day after it should be, which I'm sure is the problem. However, there is also an indicator that it is an all-day appointment which I'm pretty sure is not being used. Tried not mapping the end date, and also mapping the end date to the start date (since most of our appointments for this calendar are all day), but doing either of those makes the dates not show up on the Calendar view at all.

I think I'm totally up-to-date on the iCal parser, the Date module (latest dev version) and the Calendar module (also latest dev version).

Any suggestions on what I could do to make this work?

CommentFileSizeAuthor
#5 parser_ical.module.txt4.66 KBkarens

Comments

ekes’s picture

Title: Handle Microsoft-standard for all-day appointments » Handle events measured in days

Seems it's not just Microsoft, this is the standard thing to do for events in units of days. Picking two holiday dates feeds at random, one from apple.com:

BEGIN:VEVENT
SEQUENCE:4
TRANSP:TRANSPARENT
UID:A8989BE2-24BC-4F82-9C15-7CA91FF306C9
DTSTART;VALUE=DATE:20090907
DTSTAMP:20081113T180851Z
SUMMARY:Indenpendência do Brasil
CREATED:20081113T180830Z
DTEND;VALUE=DATE:20090908
RRULE:FREQ=YEARLY;INTERVAL=1
END:VEVENT

and one from mozilla.org

BEGIN:VEVENT
CREATED:20070429T103903Z
LAST-MODIFIED:20070429T103903Z
DTSTAMP:20070429T104243Z
UID:0bc55610-725f-11da-bc4b-e87fbad29040
SUMMARY:Eerste Paasdag
STATUS:TENTATIVE
CLASS:PRIVATE
DTSTART;VALUE=DATE:20060416
DTEND;VALUE=DATE:20060417
X-MOZILLA-RECUR-DEFAULT-INTERVAL:0
END:VEVENT

and for longer events on upcoming.com this event is from the 23rd until the 27th:-

BEGIN:VEVENT
DTSTART;VALUE=DATE:20090323
DTEND;VALUE=DATE:20090328
TRANSP:TRANSPARENT
SUMMARY:ApacheCon Europe 2009
DESCRIPTION: [Full details at http://upcoming.yahoo.com/event/988139/ ] ApacheCon is the official user conference of The Apache Software Foundation (ASF)\, drawing ASF Members\, innovators\, developers\, vendors\, and users to experience the future of Open Source development.  The 2009 Europe event will take place in  Amsterdam from November 3-7.
URL;VALUE=URI:http://upcoming.yahoo.com/event/988139/
UID:http://upcoming.yahoo.com/event/988139/
DTSTAMP:20080806T172548
LAST-UPDATED:20080806T172548
CATEGORIES:
ORGANIZER;CN=:X-ADDR:http://upcoming.yahoo.com/user/233277/
LOCATION;VENUE-UID="http://upcoming.yahoo.com/venue/49298/":Mövenpick Hotel Amsterdam City Centre @ Piet Heinkade 11\, amsterdam\, Noord-Holland 1019 BR
END:VEVENT

So I'll try and work out the most sensible place to put the logic for making these flagged as whole day events.

ekes’s picture

For the date module all day events as defined on theme output. The logic's in theme_date_all_day() {
It's all day (depending on granularity eg if it's second):- 00:00:00 -> 23:59:59 etc.
Thus if it's granularity is one day there isn't an all day event?
}

So should parser_ical:
a) subtract 1 second on detection of all day events (defined as events with no hh:mm:ss spreading over a period of a 'day' or more).
b) should it send more correct version of the ISO date (thus no hour:min:sec as it was passed) so that the date_mapper can deal with it as appropriate for the field it is going into?

I tend toward:
a) as the easier solution;
b) as the more correct solution ;-)
My biggest reservation about the addition of granularity to events where there was none is I can see timezone alterations then being done of them incorrectly.
a also assumes date field/date_mapper seem the wrong longer term assumption (although presently very true).

Any thoughts before diving to code?

karens’s picture

If it's in use it's in use and has to be dealt with. We need a way to know to ignore that invalid end-date if this is an all-day date, so I'm looking for something that seems to be a reliable way of telling that we're dealing with an all-day event, and then I can code the date API to handle it correctly.

One thing that occurs as I look at these is that they both use DATE with a date that has no time (in the format YYYY-MM-DD). If that's a reliable way of identifying an all-day event, and any date that looks like that is an all-day date, I can add some code to deal with it. I need more examples of ical files that do and don't use 'All day' to be sure that looking for that will give me the right results.

Parser_ical should be able to rely on the Date API parser, I need to make this change there in Date API, and then parser_ical can just use the value that has been determined.

karens’s picture

I did some more looking at this and I think the Date API parser is getting this right (the 'all_day' flag is set), we just need to tweak parser_ical to deal correctly with all day days.

I was going to make a patch but the version in HEAD has windows line endings in it, so a patch would look like a bunch of garbage to fix all those line endings, but the place to fix is in parser_ical_parse() where it is adding date info to $item->options. We should add something like the following:

if (!empty($event['all_day'])) {
  if ($key == 'DTSTART') {
    // Show start date with no time and no timezone. 
    $date = date_ical_date($event['DTSTART']);
    $item->options->$key = date_format($date, DATE_FORMAT_DATE) .';tz=';
   }
   elseif ($key == 'DTEND') {
    // Many iCal programs show the end date of an all day event as the next day, so
    // subtract one day from the end date and take the maximum of that or the start date.
    $date = date_ical_date($event['DTSTART']);
    $start_date = date_format($date, DATE_FORMAT_DATE) ;
    $date = date_ical_date($event['DTEND']);
    date_modify($date, '-1 day');
    if (date_format($date, DATE_FORMAT_DATE) > $start_date) {
     $end_date = date_format($date, DATE_FORMAT_DATE) ;
    }
    else {
      $end_date = $start_date;
  }
   $item->options->$key = $end_date.';tz=';
  }
}

Then the date mapper needs some adjustments to deal correctly with these values if it encounters them.

That will format the date as YYYY-MM-DD with no timezone (all day events should have no timezone). Then we need to make some adjustments

karens’s picture

StatusFileSize
new4.66 KB

I've done some work to get the parser to handle RRULES and other things correctly and found we need to pass more info from the parser to the date field (see the discussion at #215979: Create a CCK date field mapper). I've reworked the parse code to change what is passed in and also flag it as coming from the VEVENT part of the CALENDAR so we can later add code to parse the VVENUE as well.

With this change in the parser, I can get repeating dates working in the mapper, at least the beginning of getting that working.

ekes’s picture

Assigned: Unassigned » ekes
Status: Active » Reviewed & tested by the community

Cheers.

Changes in DRUPAL-6--1 branch.
I'll port to 5, make releases etc. shortly.

ekes’s picture

Status: Reviewed & tested by the community » Fixed

DRUPAL-5 version done. Both in -dev versions. Will try to sync release with next date release.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.