Hire Me! I'm currently looking for my next role in developer relations and advocacy. If you've got an open role and think I'd be a fit, please reach out. You can also find me on LinkedIn.

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]>

   <cfoutput>
   <cfif not structKeyExists(eventData,"summary")>
      <h2>Unnamed Event</h2>
   <cfelse>
      <h2>#eventData.summary.data#</h2>
   </cfif>
   <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)>
   <cfelse>
      <cfset enddate = startdate>
   </cfif>
   #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>
   <p/>
   <hr>
   </cfoutput>

</cfloop>

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.