Question

When trying to create an iCal file I get a very strange issue that I cannot trace. The following is the code used and an example of an event that is set to start at 08:00 and end at 11:00. The file creates with relevant information, but when tryting to add it to Outlook an hour has been added to the end time.

DateTime eventDate = DateTime.Parse("19/06/2014");
DateTime startTime = DateTime.Parse("09:00:00");
DateTime endTime = DateTime.Parse("11:00:00");
string location = "Test Location";
string title = "Test Title";

context.Response.ContentType = "text/x-vcalendar";
string filename = String.Format("attachment; filename={0}.ics", eventname.Replace(" ", "-"));
context.Response.AddHeader("Content-disposition", filename);

context.Response.Write("BEGIN:VCALENDAR" + Environment.NewLine);
context.Response.Write("VERSION:2.0" + Environment.NewLine);
context.Response.Write("METHOD:PUBLISH" + Environment.NewLine);

context.Response.Write("BEGIN:VTIMEZONE" + Environment.NewLine);
context.Response.Write("TZID:Europe/London" + Environment.NewLine);
context.Response.Write("X-LIC-LOCATION:Europe/London" + Environment.NewLine);
context.Response.Write("BEGIN:DAYLIGHT" + Environment.NewLine);
context.Response.Write("TZOFFSETFROM:+0000" + Environment.NewLine);
context.Response.Write("TZOFFSETTO:+0100" + Environment.NewLine);
context.Response.Write("TZNAME:BST" + Environment.NewLine);
context.Response.Write("DTSTART:19700329T010000" + Environment.NewLine);
context.Response.Write("RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU" + Environment.NewLine);
context.Response.Write("END:DAYLIGHT" + Environment.NewLine);
context.Response.Write("BEGIN:STANDARD" + Environment.NewLine);
context.Response.Write("TZOFFSETFROM:+0100" + Environment.NewLine);
context.Response.Write("TZOFFSETTO:+0000" + Environment.NewLine);
context.Response.Write("TZNAME:GMT" + Environment.NewLine);
context.Response.Write("DTSTART:19701025T020000" + Environment.NewLine);
context.Response.Write("RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU" + Environment.NewLine);
context.Response.Write("END:STANDARD" + Environment.NewLine);
context.Response.Write("END:VTIMEZONE" + Environment.NewLine);

context.Response.Write("BEGIN:VEVENT" + Environment.NewLine);
context.Response.Write("ORGANIZER:MAILTO: test@domain.com" + Environment.NewLine);
context.Response.Write("UID: test2@domain.com" + Environment.NewLine);            
context.Response.Write("DTSTART:" + startDate.ToUniversalTime().ToString("yyyyMMddTHHmmssZ") + Environment.NewLine);
context.Response.Write("DTEND:" + GetMeetingEndDate(startDate, endDate).ToString("yyyyMMddTHHmmssZ") + Environment.NewLine);
context.Response.Write("DTSTAMP:" + DateTime.Now.ToUniversalTime().ToString("yyyyMMddTHHmmssZ") + Environment.NewLine);
context.Response.Write("SUMMARY:" + subject + Environment.NewLine);
context.Response.Write("DESCRIPTION:" + description + Environment.NewLine);
context.Response.Write("LAST-MODIFIED:" + DateTime.Now.ToUniversalTime().ToString("yyyyMMddTHHmmssZ") + Environment.NewLine);
context.Response.Write("PRIORITY:5" + Environment.NewLine);
context.Response.Write("LOCATION;ENCODING=QUOTED-PRINTABLE:" + location + Environment.NewLine);
context.Response.Write("CLASS:PUBLIC" + Environment.NewLine);
context.Response.Write("END:VEVENT" + Environment.NewLine);

context.Response.Write("END:VCALENDAR");

The outcome of this is for the appointment to be added to Outlook with a start time of 09:00 and an end time of 12:00. The end time has increased by one hour.

Please note that the code about is intended for British/GMT use.

I have debugged this procedure and checked all the dates as they are being set and everything is correct. Is there anything that I am missing with this? I really don't want to have to force a reduction in the end hour just so it adds properly to Outlook.

Edit:

The following is the GetMeetingEndDate function.

DateTime GetMeetingEndDate(DateTime startDate, DateTime endDate)
    {
        DateTime newDate = new DateTime();
        if (endDate < startDate)
        {
            newDate = endDate.AddHours(12);
        }
        else if (endDate == startDate)
        {
            newDate = startDate.AddDays(1).AddHours(-1);
        }
        else
        {
            newDate = endDate;
        }
        return newDate;
    }

Thank you.

Was it helpful?

Solution

In the below code:-

context.Response.Write("DTSTART:" + startDate.ToUniversalTime().ToString("yyyyMMddTHHmmssZ") + Environment.NewLine);
context.Response.Write("DTEND:" + GetMeetingEndDate(startDate, endDate).ToString("yyyyMMddTHHmmssZ") + Environment.NewLine);

the DTSTART is set to value startDate.ToUniversalTime() whereas in function GetMeetingEndDate the dates are passed without converting into UTC. Because of this startdate is always correct but iCal is treating your local enddate as UTC date. That might be causing the problem of adding extra hour. The solution is to change the below code block as

context.Response.Write("DTEND:" + GetMeetingEndDate(startDate.ToUniversalTime(), endDate.ToUniversalTime()).ToString("yyyyMMddTHHmmssZ") + Environment.NewLine);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top