Peter's Gekko

Sponsors

The Lounge

News

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
The outlook calendar, iCalendar and RFC 2445

You can exchange Outlook appointments with other applications. One way is to export or import files in the iCalendar format. In the formats supported by Outlook you will also find the vCalendar format, iCalendar is basically a newer version of this one. The iCalendar specs are based on RFC2445, it is supported by several manufacturers and can be used to interchange appointment data with non Outlook users as well.

In my case I have an applet which generates a list of appointments which are to be imported by an Outlook user. Getting this to work was a little more complicated than it looked due to the somewhat cryptical language of an RFC, contradicting sources on the web and different behavior of Outlook versions. Let me share what I found.

The applet will produce a text file with an ics extension containing. The appointments are fed from a dataset, where each row describes an appointment. The contents of the file are constructed using a stringbuilder.

public class IcalMaker

{

private StringBuilder sb;

private string uid;

public string MakeCalender(IcalActiviteiten acts, bool reminders)

{

sb = new StringBuilder();

uid = Guid.NewGuid().ToString();

sb.AppendLine("BEGIN:VCALENDAR");

sb.AppendLine("PRODID:-//Microsoft Corporation//Outlook 11.0 MIMEDIR//EN");

sb.AppendLine("VERSION:2.0");

sb.AppendLine("METHOD:PUBLISH");

for (int i=0; i < acts.IcalActiviteit.Count; i++)

addEvent(acts.IcalActiviteitIdea, i, reminders);

sb.AppendLine("END:VCALENDAR");

return sb.ToString();

}

The code sets up the stringbuilder, an unique id, the opening lines and starts looping through the appointments.

Building these has a little quirk, although the code itself is very straightforward. Each event is enclosed in a BEGIN and an END line.

private void addEvent(IcalActiviteiten.IcalActiviteitRow act, int id, bool reminder)

{

sb.AppendLine("BEGIN:VEVENT");

sb.AppendLine(string.Format("DTSTART:{0:yyyyMMdd}T{1:hhmmss}", act.Datum, act.Aanvang));

sb.AppendLine(string.Format("DTEND:{0:yyyyMMdd}T{1:hhmmss}", act.Datum, act.Einde));

sb.AppendLine(string.Format("LOCATION:{0}", act.Zaal));

sb.AppendLine(string.Format("TRANSP:OPAQUE"));

sb.AppendLine(string.Format("SEQUENCE:0"));

sb.AppendLine(string.Format("UID:{0}-{1}", uid, id));

sb.AppendLine(string.Format("DTSTAMP:{0:yyyyMMdd}T{0:hhmmss}", act.Datum));

sb.AppendLine(string.Format("CATEGORIES:{0}", act.ActiviteitsNaam));

sb.AppendLine(string.Format("DESCRIPTION:{0}", "Your description here");

sb.AppendLine(string.Format("SUMMARY:{0}", act.ActiviteitsNaam));

sb.AppendLine("PRIORITY:5");

sb.AppendLine("X-MICROSOFT-CDO-IMPORTANCE:1");

sb.AppendLine("CLASS:PUBLIC");

if (reminder)

{

sb.AppendLine("BEGIN:VALARM");

sb.AppendLine("TRIGGER:-PT15M");

sb.AppendLine("ACTION:DISPLAY");

sb.AppendLine("DESCRIPTION:Reminder");

sb.AppendLine("END:VALARM");

}

sb.AppendLine("END:VEVENT");

}

The format and value of the event start (DTSTART) and end (DTEND) time needs special attention. Anyone who ever took their outlook data to a different time zone will have noticed all appointments moving in time when changing the time zone in Windows. Personally I find this frustrating, for instance when preparing for the PDC (in the Netherlands) I entered all sessions I didn't want to miss in my Outlook schedule. Having arrived in LA after adapting to the local culture Outlook wanted me to turn up in the middle of the night to hear Anders Hejlsberg speak. You can wake me up any time for such a presentation but I just known he won't be there. Outlook stores the times in UTC time and presents them using the actual time zone. Moving to another time zone, moves the appointments.

When feeding Outlook from an external application this same problem pops up. My application, Syllabus plus scheduling software, has no notion of time zones at all; it just thinks local time. At first sight you could recalculate all times to UTC times. But then you have to be aware of the dates the offset from UTC changes, that is the date the environment changes to day-lights saving time. You will end up with quite complicated configuration settings in your app. According to RFC 2445 a time zone can be added to a timestamp. But in that case you have to set up a time zone administration in you app, not very compelling either.

The good thing is that you can enter timestamps as so-called floating time, which indicates that the moment in time is determined by the local time zone. The bad thing is that Outlook 2000 does not support this, Outlook 2003 does and Outlook 2007 will bombard you with error messages telling it doesn't. To make things even more confusing I found my Outlook 2007 complaining about nothing, it does import all floating time events and does translate them quite right. For the moment I just have to tell my users to ignore the error message when using Outlook 2007.

The difference between a floating time and an UTC time is one letter. This is an UTC time

"DTSTART:{0:yyyyMMdd}T{1:hhmmss}Z"

And this a floating time

"DTSTART:{0:yyyyMMdd}T{1:hhmmss}"

The UTC time has an extra Z.

Another property which needs some explanation is UID, the unique ID. This is supposed to be unique for every event. In my case I generate a guid for the series and append the event's sequence. Outlook will not complain when the ID is not unique, but it is part of the spec.

In case you want to add a reminder to the appointment add a VALARM. In the example this is hard coded at 15 minutes : TRIGGER:-PT15M

Using this code I have all information Outlook needs in one string. A web app can write this directly to the response, following the minimal code to get that done.

IcalMaker icm = new IcalMaker();

IcalActiviteiten acts = getAppointmentData();

Response.Clear();

Response.ContentType = "application/binary";

Response.AddHeader("Content-Disposition", "attachment;filename=YourAppointments.ics");

Response.Write(icm.MakeCalender(acts, CheckBoxReminders.Checked));

Response.Flush();

Response.End();

Adding the appointments to outlook is now a click away.

That's it. I don't claim to understand all settings and fiddlings. But it works well; and that's enough for the moment.


Posted 01-17-2007 8:17 AM by pvanooijen

[Advertisement]

Comments

slolife wrote re: The outlook calendar, iCalendar and RFC 2445
on 01-17-2007 12:20 PM

Check out http://www.codeproject.com/vb/net/vcalendar.asp for a .net class that has similar code.

Good stuff on the timezone stuff, something I didn't spend a lot of time with in my code.

I'll also have to add support for the X-MICROSOFT-CDO-IMPORTANCE field.

pvanooijen wrote re: The outlook calendar, iCalendar and RFC 2445
on 01-18-2007 2:29 AM

Nice article !

I got the list of all fields by reverse engineering. Saved an appointment in Outlook as iCalender and used notepad to see what it looked like. Don't know what every detail stands for though..

Mike wrote re: The outlook calendar, iCalendar and RFC 2445
on 01-18-2007 2:01 PM

Nice post.

Years ago I wrote ASP code to generate vCards, so I can appreciate what you went through with the RFC (I did the same at that time).  It's been on the back of my mind to write some code for generating vCalendars... thanks for sharing!

Mike

The Original .NET Geek wrote The outlook calendar, iCalendar and RFC 2445
on 01-29-2007 11:38 AM

So I have been using the google calendar for some time now since I let google manage my domains . One

Milo wrote re: The outlook calendar, iCalendar and RFC 2445
on 03-14-2007 1:51 PM

"Z versus T"

That's not the case.  According to rfc2445 section 4.3.5 it's always [date]T[time], where [time] may end with a Z (indicating UTC time) or without one (indicating a floating time).

So this is an UTC time:

"DTSTART:{0:yyyyMMdd}T{1:hhmmss}Z"

And this a floating time

"DTSTART:{0:yyyyMMdd}T{1:hhmmss}"

pvanooijen wrote re: The outlook calendar, iCalendar and RFC 2445
on 03-15-2007 6:27 AM

Thanks Milo. You're right, the content is updated.

Misha wrote re: The outlook calendar, iCalendar and RFC 2445
on 07-06-2007 10:14 AM

I have been trying to write a icalendar file to show time as 'Out of Office' instead of the default 'Busy'.

would you know how to set this?

pvanooijen wrote re: The outlook calendar, iCalendar and RFC 2445
on 07-13-2007 5:21 AM

Isn't that an outlook property ? Not part of icalender ?

kallien wrote re: The outlook calendar, iCalendar and RFC 2445
on 10-19-2007 8:01 AM

What is the way to set the time as 'Out Of Office'?

Peter's Gekko wrote Implement a “standard” document ? Be strict when you write but forgiving when you read
on 11-09-2007 4:36 AM

A notorius document standard is iCal which describes a (text based) standard to exchange scheduling appointments

Alex wrote re: The outlook calendar, iCalendar and RFC 2445
on 01-06-2008 10:38 PM

Hi,

I've been trying to do a simple iCalendar implementation in php.  You'll find the threads below with discussions of various aspects below.  Mac has proven to be very easy.  Outlook seems to fight every step.

Your implementation above does not include the "folding" required by RFC 2445, nor the replacement of characters " , ; : etc" as I have found in other examples and advice given to me.  Am I missing something?

If you have an opportunity, check these out and comment, as well.

forums.devshed.com/.../preg-replace-explaination-needed-497498.html

forums.devshed.com/.../if-you-have-outlook-or-icalendar-i-need-your-iballs-496241.html

forums.devshed.com/.../dating-a-google-calendar-494912.html

forums.devshed.com/.../icalendar-and-outlook-495158.html

Alex

vishal wrote re: The outlook calendar, iCalendar and RFC 2445
on 01-11-2008 5:30 AM

Great Article.

congrats

But Sir I want to know that what will be the size of iCal file in memory and how can we calculate that size using bit information of that file using hex viewer.

Regards

Vishal

email:    sbvishal@gmail.com

pvanooijen wrote re: The outlook calendar, iCalendar and RFC 2445
on 01-11-2008 6:02 AM

@Alex. My implementation is not a full implementaion of RFC 2445. My point is that a lot of email clients don't follow RFC 2445 either, especially Outlook is bad. Being a good citizen you should implement as much of the RFC as possible but at the same time you have to be carefull the consuming apps don't trip over the content. I stated this in more word here

codebetter.com/.../implement-a-standard-document-be-strict-when-you-write-but-forgiving-when-you-read.aspx

@vishal: You can read the size of the result file when save it. But that's not the amount of memory it takes to build it. In case that troubles you you need a profiler.

Sean wrote re: The outlook calendar, iCalendar and RFC 2445
on 01-18-2008 10:12 AM

I need to go the other way.... I want to take advantage of the easy to use Calendar interface for a content publisher to make a calendar in outlook export an iCalendar that I can place on the site to read in the event/appointment information via ASP.NET. This to me would be much easier than having to create an event manager and storing the data etc myself. any thoughts? anybody?

pvanooijen wrote re: The outlook calendar, iCalendar and RFC 2445
on 01-21-2008 8:03 AM

Should be no problem. You can save the outlook schedule directly as an ical file. It's in the export wizard of Outlook's file menu.

gui wrote re: The outlook calendar, iCalendar and RFC 2445
on 02-08-2008 11:01 AM

This class is not defined "IcalActiviteiten"

What is it suppost to be? Can you add it?

pvanooijen wrote re: The outlook calendar, iCalendar and RFC 2445
on 02-11-2008 5:17 AM

Icalactiviteiten is an interface. The members of this interface describe the activity to be published. So that's the point your own functionality enters the code.

Eric wrote re: The outlook calendar, iCalendar and RFC 2445
on 03-07-2008 7:20 PM

Can anyoned explain how to include the Attendees, so instead of manually click the Invite Attendees button and add the emails in the TO field, well the form field will take the emails written by the client and it will implemented into the ics file ready for the author to click SEND ??? please can this be done.

email me your answer to:  djzomby@hotmail.com

pvanooijen wrote re: The outlook calendar, iCalendar and RFC 2445
on 03-08-2008 3:36 PM

What about reverse engineering. Create such an appointment and save it as ical (In the Outlook menu). Which will show you the ical's content.

Email the answer ?

codebetter.com/.../A-blog-is-not-a-helpdesk.aspx

Eric wrote re: The outlook calendar, iCalendar and RFC 2445
on 03-18-2008 1:26 PM

Ive already done that, the ics is attach. The only thing is, the attendee does nothing, I can add and change the email for the FROM (Organizer) but thats it, and its not good enough. Ive been searching for over 2 month just to include 1 extra email in the Required: field. My form is built so when the client submits, the author accepts it and it has to be save in the client calendar and the boardroom calendar (author). Any idea?

www.experts-exchange.com/.../Q_23178137.html

pvanooijen wrote re: The outlook calendar, iCalendar and RFC 2445
on 03-21-2008 4:35 PM

Eric,

May I suggest some TDD to get the thing working ? Mock (stub) the desired result. See if it behaves well. Separate that from the form to construct the thing.

Amy K wrote re: The outlook calendar, iCalendar and RFC 2445
on 05-21-2008 12:42 PM

Out of office is

X-MICROSOFT-CDO-BUSYSTATUS:OOF

Steve P wrote re: The outlook calendar, iCalendar and RFC 2445
on 07-04-2008 9:55 AM

Floating time is still not floating in Outlook 2007.

I'm writing an app to enter flight information into a user's calendar, so most of the time the return leg originates in a different time zone to the outward leg.

I have ways of working out the timezone and dst parameters for each airport which would allow me populate with UTC time or specify a VTIMEZONE but floating times are a much better solution cos:

a) It means I don't have to do the work to figure out airport timezone

b) I don't have to create additional database tables to store the timezone data

c) I don't have to worry about maintaining the timezone database in years to come

but most importantly

d) Users won't keep phoning up to say that the calendar entries are going in at the wrong time

- to get an email saying your return flight from LAX to LHR is taking off at 15:30 which contains a calendar entry where the flight takes off at 09:30 is very confusing

- IMO most users would like to see their calendars displayed in local time irrespective of what timezone they are in

I've been quite a way through the RFC before discovering this atricle (which is very good BTW and a far preferable option than reading the RFC) ... and had already tried out the floating time format and imported into Outlook 2002 - it didn't work - no suprises there

Most of our customers will be using Outlook 2003-2007 so if floating times work my problem goes away - so I got a collegue to load the ics into 2007 - sadly it's just the same as 2002

- don't know if I'm doing somwething wrong - but it's not exactly rocket science removing the Z at the end of the date string

Tried to create a floating appointment in 2007 to reverse engineer, but found I can set the time zone to anywhere in the world for the appointment, but not set it to 'floating timezone'

I would have given up long ago and gone down the airport timezone route had it not been for the glimmer of hope offered by this article

I have seen some posts which suggest that floating time only works for all day appointments - forums.teamsnap.com/.../206

- any ideas?

Steve

outlook calendar wrong language wrote outlook calendar wrong language
on 07-07-2008 6:46 AM

Pingback from  outlook calendar wrong language

Pratik wrote re: The outlook calendar, iCalendar and RFC 2445
on 09-18-2008 5:10 AM

A detail of the interface IcalActiviteiten would help to no end. Since, the variable names are not intuitive (at least to me), can't make out what value to pass to them.

pvanooijen wrote re: The outlook calendar, iCalendar and RFC 2445
on 09-22-2008 4:27 PM

It's meant to be enigmatic. It's nothing else but fodder to feed your ical appointments.. The iCal names, the fits CAPITALIZED part of the textlines are important.

Gregguz wrote re: The outlook calendar, iCalendar and RFC 2445
on 10-13-2008 4:53 AM

UTC vs. floating time

You can use ToUniversalTime method of DateTime c# class and the date and time will be generated correctly for Outlook, it won't also generate any errors. Good Luck.

string.Format("DTSTART:{1:yyyyMMddTHH0000}Z",

StartDate.ToUniversalTime())

Sam wrote re: The outlook calendar, iCalendar and RFC 2445
on 11-10-2008 7:49 PM

The clients server is hosted at CST and when adding appoinments using the vcs file as above times are changed to one hr ahead.  The client could be in anyyime zone. Is there a way for me to tell the vcs file to ignore the GMT format and just take the datetime I pass in.

James Skemp wrote re: The outlook calendar, iCalendar and RFC 2445
on 03-19-2009 10:57 AM

Late comment: Has anyone gotten the reminder functionality to work?

I've tried this and various tweaks, but neither Outlook 2003 nor 2007 accept this, when the appointment is sent as an attachment, via email.

Add a Comment

(required)  
(optional)
(required)  
Remember Me?