I am creating an .ics file that when opened (via Outlook) inserts a
meeting into the calendar.
All works fine unless the date and time I'm inserting happens to occur
on the hour the time changes due to daylight savings.
For example in 2004 the hours changed at 2:00 AM on April 4th (the
first Sunday of April). Only on this day, if the start hour is 2 (2:00
AM, 2:15 AM, 2:45 AM), then an extra hour gets added so that 2:00 AM
becomes 3:00 AM, and 2:15 AM becomes 3:15 AM, and so on.
I attempted a terrible hack that checks whether the date and time are
on the first Sunday in April of the year, and the hour is 2, and if
true then I perform a DateTime.AddHours(-1). However I then get an
Outlook error stating 'Cannot import vCalendar file. This time is not
valid due to daylight saving time'
Here is my code. Any suggestions or work arounds? Help appreciated,
thanks.
private void CreateMeeting()
{
string startYear="";
string endYear="";
string startMonth="";
string endMonth="";
string startDay="";
string endDay ="";
string strStartTime="";
string strEndTime="";
string strTimeStamp="";
const string c_strTimeFormat = "yyyyMMdd\\THHmmss\\Z";
//- VCalendar file format: export calendar meeting from outlook and
open in notepad to see file structure
const string VCAL_FILE =
"BEGIN:VCALENDAR\n" +
"PRODID:-//Microsoft Corporation//Outlook 9.0 MIMEDIR//EN\n" +
"VERSION:2.0\n" +
"METHOD:PUBLISH\n" +
"BEGIN:VEVENT\n\n" +
"DTSTART{0}\n" +
"DTEND{1}\n" +
"LOCATION:{2}\n" +
"TRANSP:OPAQUE\n" +
"SEQUENCE:0\n" +
"UID:te**@teststestetse.ca\n" +
"DTSTAMP:{5}\n" +
"DESCRIPTION:{3}\n" +
"SUMMARY:{4}\n\n" +
"PRIORITY:5\n" +
"CLASS:PUBLIC\n" +
"BEGIN:VALARM\n" +
"TRIGGER:PT15M\n" +
"ACTION:DISPLAY\n" +
"DESCRIPTION:Reminder\n" +
"PRIORITY:5\n" +
"END:VALARM\n" +
"END:VEVENT\n" +
"END:VCALENDAR" ;
string strSQL = GetSql();
DataSet ds = Common.GetDataSet(strSQL, "Page_Load");
DataRow dr = ds.Tables[0].Rows[0];
string loc = dr["location"].ToString();
string subj = dr["title"].ToString();
DateTime dtmEndDate;
DateTime dtmStartDate = DateTime.Parse(dr["date"].ToString());
DateTime dtmStartTime = DateTime.Parse(dr["starttime"].ToString());
DateTime dtmEndTime = DateTime.Parse(dr["endtime"].ToString());
int intAllDayEvent = int.Parse(dr["alldayevent"].ToString());
//-HACK TO ATTEMPT TO CORRECT 1st DAY APRIL HOURS
if (dtmStartDate.Month == 4 && dtmStartDate.Day < 7 &&
dtmStartDate.DayOfWeek == DayOfWeek.Sunday && dtmStartTime.Hour == 2)
{
dtmStartTime = dtmStartTime.AddHours(-1);
dtmEndTime = dtmEndTime.AddHours(-1);
}
if (intAllDayEvent==1) //-All Day Event (diff format than times)
{
//-Year, Month, Day
dtmEndDate = dtmStartDate.AddDays(1);
startYear = dtmStartDate.Year.ToString(); //4 digits
endYear = dtmEndDate.Year.ToString(); //4 digits
startMonth = AffixZero(dtmStartDate.Month.ToString()); //2 digits
endMonth = AffixZero(dtmEndDate.Month.ToString()); //2 digits
startDay = AffixZero(dtmStartDate.Day.ToString()); //2 digits
endDay = AffixZero(dtmEndDate.Day.ToString()); //2 digits
string strStartDate=string.Format("{0}{1}{2}",startYear,s tartMonth,startDay);
string strEndDate=string.Format("{0}{1}{2}",endYear,endMo nth,endDay);
strStartTime=string.Format(";VALUE=DATE:{0}",strSt artDate);
strEndTime=string.Format(";VALUE=DATE:{0}",strEndD ate);
strTimeStamp=string.Format("{0}T200000Z",strStartD ate);
}
else //-Times (diff format than if 'all day event')
{
dtmEndDate = dtmStartDate;
string strTempStartTime = string.Format("{0} {1}",
dtmStartDate.ToShortDateString(),dtmStartTime.ToLo ngTimeString());
string strTempEndTime = string.Format("{0} {1}",
dtmEndDate.ToShortDateString(),dtmEndTime.ToLongTi meString());
strTimeStamp = (DateTime.Parse(strTempStartTime)).ToUniversalTime ().ToString(c_strTimeFormat);
strStartTime = string.Format(":{0}", strTimeStamp);
strEndTime = string.Format(":{0}",
(DateTime.Parse(strTempEndTime)).ToUniversalTime() .ToString(c_strTimeFormat));
}
//-Event Info
string strEventInfo = "";
//-Details
string strDetails = AddEscapeChars(dr["details"].ToString());
if (strDetails.Length > 0)
{
strEventInfo = string.Format("{0}Details -
{1}{2}",strEventInfo,strDetails,"\\n");
}
//-Weblink
string strWeblink = dr["url"].ToString();
if (strWeblink.Length > 0)
{
strEventInfo = string.Format("{0}Web Link -
{1}{2}",strEventInfo,strWeblink,"\\n");
}
if (strEventInfo.Length > 0)
{
strEventInfo = string.Format("{1}Event
Information{1}-----------------------------{1}{0}",
strEventInfo,"\\n");
}
//-Contact Info
string strContactInfo =
Common.FormatContactInfo(dr["contactname"].ToString(),
dr["contactextension"].ToString(), dr["contactemail"].ToString(), "",
false);
string desc = string.Format("{0}{1}", strEventInfo, strContactInfo);
//-convert string to array of bytes
string vCalendarFile =
String.Format(VCAL_FILE,strStartTime,strEndTime,lo c,desc,subj,strTimeStamp);
System.Text.ASCIIEncoding ascii =new System.Text.ASCIIEncoding();
byte [] vCalbytes= ascii.GetBytes(vCalendarFile);
//-writes 'file' output to stream:
Response.Clear();
Response.ClearHeaders();
Response.ContentType="text/calendar";
Response.AddHeader("content-disposition","inline;
filename=Event.ics"); //sends as .ics file so machine knows to open in
Outlook
Response.BinaryWrite(vCalbytes);
Response.End();
}