I've finished the iCal CFC. The code has not been heavily tested, so use with care. Here is an example use of it:

<cfset theFile = expandPath("./christianholidays.ics")>
<cffile action="read" file="#theFile#" variable="data">

<cfset ical = createObject("component","ical")>
<cfset results = ical.getEvents(data)>

<cfloop index="x" from="1" to="#arraylen(results)#">

   <cfset eventData = results[x]>

   <cfif not structKeyExists(eventData,"summary")>
      <h2>Unnamed Event</h2>
   <cfset startDate = ical.icalParseDateTime(eventData.dtstart.data)>
   <cfif structKeyExists(eventData,"dtend")>
      <cfset endDate = ical.icalParseDateTime(eventData.dtend.data)>
   <cfelseif structKeyExists(eventData,"duration") and eventData.duration.data is not"P1D">
      <cfset endDate = ical.icalParseDuration(eventData.duration.data,startdate)>
      <cfset enddate = startdate>
   #dateFormat(startDate,"mm/dd/yy")#<cfif dateFormat(startDate,"mm/dd/yy") neq dateFormat(endDate,"mm/dd/yy")> - #dateFormat(endDate,"mm/dd/yy")#</cfif><br>
   <cfif structKeyExists(eventData,"description")>#eventData.description.data#</cfif>


As you can see - there is one main method, getEvents, that will parse the events from an iCal string. (iCal also supports "TODO"s I believe, and I'll look into adding support for that later.) I've also added a few supporting functions. iCalParseDateTime will parse the datetime strings in iCal files. iCalParseDuration will translate the duration value by adding it to a passed in date (such as the starting date).

You can download the code here.