Generating an iCalendar .ics file using ColdFusion
I've been working on a small project at work to allow a user to click a link from an event registration confirmation email, which will open a .ics file in the browser. This special file is in the iCalendar format, and is recognized by MS Outlook, Mozilla Sunbird, and other calendaring tools. It creates an entry in your calendar, with a 30 minute reminder alert, to help you remember to attend the webinar event you registered for. I learned from the vCal() function on cflib.org, and will be submitting my new iCalUS() UDF soon. But here is the code now, as it takes some time to get verified for inclusion on the CFLib.org site.
Download the code in a zip file.
I wrote the function to work in the U.S. and account for daylight savings time. Hopefully developers outside the U.S. can adapt this code to fit their timezones accordingly. Here is the code used for the test submission form and cfcontent/cfheader tags for the following demo.
<P>
<cfoutput>
<form method="post">
<table>
<tr>
<td align="right">Organizer name</td>
<td><input type="Text" name="on" value="#Form.on#" size="30"></td>
</tr>
<tr>
<td align="right">Organizer email</td>
<td><input type="Text" name="oe" value="#Form.oe#" size="30"></td>
</tr>
<tr>
<td align="right">Description</td>
<td><input type="Text" name="desc" value="#Form.desc#" size="60"> (use \n sequences for newlines)</td>
</tr>
<tr>
<td align="right">Subject</td>
<td><input type="Text" name="sub" value="#Form.sub#" size="30"></td>
</tr>
<tr>
<td align="right">Location</td>
<td><input type="Text" name="loc" value="#Form.loc#" size="30"></td>
</tr>
<tr>
<td align="right">Start Date/Time</td>
<td><input type="Text" name="st" value="#Form.st#" size="20"> (format: <b>m/d/yyyy HH:mm</b> OR <b>h:mm TT</b> -- this is Eastern time)</td>
</tr>
<tr>
<td align="right">End Date/Time</td>
<td><input type="Text" name="et" value="#Form.et#" size="20"> (format: <b>m/d/yyyy HH:mm</b> OR <b>h:mm TT</b> -- this is Eastern time)</td>
</tr>
</table>
<input type="Submit" name="Submit" value="Submit">
</form>
</cfoutput>
<cfif IsDefined("Form.Submit")>
<cfset eventStr = StructNew()>
<cfset eventStr.organizerName = Form.on>
<cfset eventStr.organizerEmail = Form.oe>
<cfset eventStr.startTime = ParseDateTime(Form.st)>
<cfset eventStr.endTime = ParseDateTime(Form.et)>
<cfset eventStr.subject = Form.sub>
<cfset eventStr.location = Form.loc>
<cfset eventStr.description = Form.desc>
<cfcontent type="text/calendar" reset="Yes">
<cfheader name="Content-Disposition" value="inline; filename=newAppointment.ics"><cfoutput>#iCalUS(eventStr)#</cfoutput>
</cfif>
Here is a demo of this in action.
-- Update 4/10/08: I submitted the UDF to cflib.org today. Hopefully Ray will post it soon. --


Go Whitesox!!
thanks for this great post. just curious, how can we add additional fields so that we can add some event details? we want to integrate into outlook
I was trying to put your code to our website. when I run it, I can create the iCal file, but when I open it, I got a error to import ti the outlook.
The error message: This error can appear if you have attempted to save a recurring Lunar appointment in iCalendar format.
To avoid this error, set the appointment option to Gregorian instead of Lunar.
here is my test website:
http://1bosdev1.conferon.com/demo/demo2007/Agenda/...
Please help me. We would like to use your code in our application.
Thanks
Jason
http://blog.webdh.com/demos/iCalUS.zip
http://severinghaus.org/projects/icv/
Thanks,
Robert
Thanks,
Robert
Any suggestions? I really want to use this code but I seem to be tripping at the finish line when it goes to save to Outlook.
The problem seems to be in the "direct" delivery via cfcontent.
I've tried the exact same setup with IIS/CF7 (successful) and Apache2/Railo (no success)
Verified the mime definition of ics in both servers,
IIS: ics=applicatin/octet-stream
Ap: ics=text/calendar
modified the Mimetypes in Apache to match that of IIS -> Still no success
Wondered if you could explain to me how to adjust the timezone of the iCalUS() script. Specifically to default to pacific time. I also had a hard time decyphering how the time offset for daylight savings works. Thanks in advance, very useful function.
On 3/30, I replied back with:
In the code, these values are setup for Eastern time
vCal = vCal & "TZOFFSETFROM:-0500" & CRLF;
vCal = vCal & "TZOFFSETTO:-0400" & CRLF;
so to modify to Pacific, I think you'd change to this (2 spots in the code)
vCal = vCal & "TZOFFSETFROM:-0800" & CRLF;
vCal = vCal & "TZOFFSETTO:-0700" & CRLF;
The DST should just work, it uses the logic (copied from Wikipedia) which started in 2007, most of the United States and Canada observe DST from the second Sunday in March to the first Sunday in November. This corresponds to these 2 lines of code.
vCal = vCal & "RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=2SU;BYMONTH=3" & CRLF;
vCal = vCal & "RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=11" & CRLF;