Exemple #1
0
        public void SystemTimeZone2()
        {
            System.TimeZoneInfo tzi = System.TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time");
            Assert.IsNotNull(tzi);

            iCalendar iCal = new iCalendar();
            ITimeZone tz   = iCal.AddTimeZone(tzi, new DateTime(2000, 1, 1), false);

            Assert.IsNotNull(tz);

            iCalendarSerializer serializer = new iCalendarSerializer();

            serializer.Serialize(iCal, @"Calendars\Serialization\SystemTimeZone2.ics");

            // Ensure the time zone transition works as expected
            // (i.e. it takes 1 hour and 1 second to transition from
            // 2003-10-26 1:59:59 AM to
            // 2003-10-26 2:00:00 AM)
            iCalDateTime dt1    = new iCalDateTime(2003, 10, 26, 1, 59, 59, tz.TZID, iCal);
            iCalDateTime dt2    = new iCalDateTime(2003, 10, 26, 2, 0, 0, tz.TZID, iCal);
            TimeSpan     result = dt2 - dt1;

            Assert.AreEqual(TimeSpan.FromHours(1) + TimeSpan.FromSeconds(1), result);

            // Ensure another time zone transition works as expected
            // (i.e. it takes negative 59 minutes and 59 seconds to transition from
            // 2004-04-04 1:59:59 AM to
            // 2004-04-04 2:00:00 AM)
            dt1    = new iCalDateTime(2004, 4, 4, 1, 59, 59, tz.TZID, iCal);
            dt2    = new iCalDateTime(2004, 4, 4, 2, 0, 0, tz.TZID, iCal);
            result = dt2 - dt1;
            Assert.AreEqual(TimeSpan.FromHours(-1) + TimeSpan.FromSeconds(1), result);
        }
Exemple #2
0
        public void SystemTimeZone2()
        {
            System.TimeZoneInfo tzi = System.TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time");
            Assert.IsNotNull(tzi);

            iCalendar iCal = new iCalendar();
            ITimeZone tz   = iCal.AddTimeZone(tzi);

            Assert.IsNotNull(tz);

            iCalendarSerializer serializer = new iCalendarSerializer();

            serializer.Serialize(iCal, @"Calendars\Serialization\SystemTimeZone2.ics");

            iCalDateTime dt1    = new iCalDateTime(2003, 10, 26, 0, 59, 59, tz.TZID, iCal);
            iCalDateTime dt2    = new iCalDateTime(2003, 10, 26, 1, 0, 0, tz.TZID, iCal);
            TimeSpan     result = dt2 - dt1;

            Assert.AreEqual(TimeSpan.FromHours(1) + TimeSpan.FromSeconds(1), result);

            dt1    = new iCalDateTime(2004, 4, 4, 1, 59, 59, tz.TZID, iCal);
            dt2    = new iCalDateTime(2004, 4, 4, 2, 0, 0, tz.TZID, iCal);
            result = dt2 - dt1;
            Assert.AreEqual(TimeSpan.FromHours(-1) + TimeSpan.FromSeconds(1), result);
        }
Exemple #3
0
        public void SystemTimeZone2()
        {
            System.TimeZoneInfo tzi = System.TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time");
            Assert.IsNotNull(tzi);

            iCalendar iCal = new iCalendar();
            ITimeZone tz = iCal.AddTimeZone(tzi, new DateTime(2000, 1, 1), false);
            Assert.IsNotNull(tz);

            iCalendarSerializer serializer = new iCalendarSerializer();
            serializer.Serialize(iCal, @"Calendars\Serialization\SystemTimeZone2.ics");

            // Ensure the time zone transition works as expected
            // (i.e. it takes 1 hour and 1 second to transition from
            // 2003-10-26 12:59:59 AM to
            // 2003-10-26 01:00:00 AM)
            iCalDateTime dt1 = new iCalDateTime(2003, 10, 26, 0, 59, 59, tz.TZID, iCal);
            iCalDateTime dt2 = new iCalDateTime(2003, 10, 26, 1, 0, 0, tz.TZID, iCal);
            TimeSpan result = dt2 - dt1;
            Assert.AreEqual(TimeSpan.FromHours(1) + TimeSpan.FromSeconds(1), result);

            // Ensure another time zone transition works as expected
            // (i.e. it takes negative 59 minutes and 59 seconds to transition from
            // 2004-04-04 01:59:59 AM to
            // 2004-04-04 02:00:00 AM)
            dt1 = new iCalDateTime(2004, 4, 4, 1, 59, 59, tz.TZID, iCal);
            dt2 = new iCalDateTime(2004, 4, 4, 2, 0, 0, tz.TZID, iCal);
            result = dt2 - dt1;
            Assert.AreEqual(TimeSpan.FromHours(-1) + TimeSpan.FromSeconds(1), result);
        }
        public void SystemTimeZone1()
        {
//            System.TimeZoneInfo tzi = System.TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time");
            System.TimeZoneInfo tzi = System.TimeZoneInfo.FindSystemTimeZoneById("America/Denver");
            Assert.IsNotNull(tzi);

            iCalendar iCal = new iCalendar();
            ITimeZone tz = iCal.AddTimeZone(tzi, new DateTime(2000, 1, 1), false);

            iCalendarSerializer serializer = new iCalendarSerializer();
            serializer.Serialize(iCal, @"Calendars/Serialization/SystemTimeZone1.ics");

            // Ensure the time zone transition works as expected
            // (i.e. it takes 1 hour and 1 second to transition from
            // 2003-10-26 1:59:59 AM to
            // 2003-10-26 2:00:00 AM)
            iCalDateTime dt1 = new iCalDateTime(2003, 10, 26, 1, 59, 59, tz.TZID, iCal);
            iCalDateTime dt2 = new iCalDateTime(2003, 10, 26, 2, 0, 0, tz.TZID, iCal);

            TimeSpan result = dt2 - dt1;
            Assert.AreEqual(TimeSpan.FromHours(1) + TimeSpan.FromSeconds(1), result);

            // Ensure another time zone transition works as expected
            // (i.e. it takes negative 59 minutes and 59 seconds to transition from
            // 2004-04-04 01:59:59 AM to
            // 2004-04-04 02:00:00 AM)
            
            // NOTE: We have a negative difference between the two values
            // because we 'spring ahead', and an hour is lost.
            dt1 = new iCalDateTime(2004, 4, 4, 1, 59, 59, tz.TZID, iCal);
            dt2 = new iCalDateTime(2004, 4, 4, 2, 0, 0, tz.TZID, iCal);
            result = dt2 - dt1;
            Assert.AreEqual(TimeSpan.FromHours(-1) + TimeSpan.FromSeconds(1), result);            
        }
        /// <summary>
        /// Function is called to create the course ics file
        /// Function is called everytime the course calendar needs to be updated
        /// </summary>
        /// <param name="id"></param>
        public void CreateCourseCalendar(int id)
        {
            //Get the Course
            var course = (from d in db.Courses
                          where d.ID == id
                          select new
            {
                d.StartDate,
                d.EndDate,
                d.Prefix,
                d.Number,
                d.Semester,
                d.Year,
                d.CourseMeetings,
                d.CourseBreaks,
                d.ID
            }).FirstOrDefault();


            //get course events
            var events = (from e in db.Events
                          where e.Poster.AbstractCourseID == ActiveCourseUser.AbstractCourseID &&
                          e.StartDate >= course.StartDate &&
                          e.StartDate <= course.EndDate &&
                          e.Approved
                          select new
            {
                e.StartDate,
                e.EndDate,
                e.Title,
                e.Description
            }).ToList();

            //Create the calendar object
            iCalendar courseCalendar = new iCalendar();

            //initalize the Calendar object
            courseCalendar.AddTimeZone(DateTimeExtensions.GetTimeZone(((Course)ActiveCourseUser.AbstractCourse).TimeZoneOffset));
            courseCalendar.Method    = "PUBLISH";
            courseCalendar.Name      = "VCALENDAR";
            courseCalendar.Version   = "2.0";
            courseCalendar.ProductID = "-//Washington State University//PLUS.OSBLE.org//EN";
            courseCalendar.Scale     = "GREGORIAN";
            courseCalendar.AddProperty("X-WR-CALNAME", course.Prefix + "-" + course.Number + "-" + course.Semester + "-" + course.Year);

            //get course breaks
            if (ActiveCourseUser.AbstractCourse is Course && ((ActiveCourseUser.AbstractCourse as Course).ShowMeetings == true))
            {
                foreach (CourseMeeting cm in course.CourseMeetings)
                {
                    StringBuilder rpPattern = new StringBuilder("FREQ=WEEKLY;UNTIL=");
                    rpPattern.Append(new iCalDateTime(course.EndDate.UTCToCourse(ActiveCourseUser.AbstractCourseID)).ToString(@"yyyyMMdd\THHmmss\Z"));
                    rpPattern.Append(";WKST=SU;BYDAY=");
                    if (cm.Sunday)
                    {
                        rpPattern.Append("SU,");
                    }
                    if (cm.Monday)
                    {
                        rpPattern.Append("MO,");
                    }
                    if (cm.Tuesday)
                    {
                        rpPattern.Append("TU,");
                    }
                    if (cm.Wednesday)
                    {
                        rpPattern.Append("WE,");
                    }
                    if (cm.Thursday)
                    {
                        rpPattern.Append("TH,");
                    }
                    if (cm.Friday)
                    {
                        rpPattern.Append("FR,");
                    }
                    if (cm.Saturday)
                    {
                        rpPattern.Append("SA");
                    }

                    //trim trailing comma if it is there
                    if (rpPattern[rpPattern.Length - 1] == ',')
                    {
                        rpPattern.Remove(rpPattern.Length - 1, 1);
                    }

                    RecurringComponent recurringComponent = new RecurringComponent();
                    RecurrencePattern  pattern            = new RecurrencePattern(rpPattern.ToString());

                    DDay.iCal.Event evt = courseCalendar.Create <DDay.iCal.Event>();
                    //may cause issues
                    DateTime evtStart = DateTime.SpecifyKind(course.StartDate, DateTimeKind.Utc);
                    evtStart = evtStart.Add(cm.StartTime.TimeOfDay);
                    DateTime evtEnd = DateTime.SpecifyKind(course.StartDate, DateTimeKind.Utc);
                    evtEnd = evtEnd.Add(cm.EndTime.TimeOfDay);

                    //we need to test if right NOW is in DST.
                    //case: course starts during DST, and it's now after DST, result: after DST event is now wrong.
                    DateTime currentTime = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day,
                                                        evtStart.Hour, evtStart.Minute, evtStart.Second, DateTimeKind.Utc);
                    bool isDaylight = TimeZoneInfo.Local.IsDaylightSavingTime(currentTime.UTCToCourse(ActiveCourseUser.AbstractCourseID));

                    if (isDaylight)
                    {
                        evt.Start        = new iCalDateTime(evtStart.UTCToCourse(ActiveCourseUser.AbstractCourseID));
                        evt.End          = new iCalDateTime(evtEnd.UTCToCourse(ActiveCourseUser.AbstractCourseID));
                        evt.LastModified = new iCalDateTime(DateTime.Now);
                        evt.Summary      = cm.Name;
                        evt.Location     = cm.Location;
                        evt.RecurrenceRules.Add(pattern);
                    }
                    else //no longer DST
                    {
                        bool matchingStartDay = false;

                        /*
                         * if there happens to be a "meeting times" in the database without a day of the week associated with
                         * the meeting, we need to skip the while and switch case, otherwise it's an infinite loop!
                         */
                        bool meetingTimeWithoutDaysOfWeek = cm.Sunday || cm.Monday || cm.Tuesday || cm.Wednesday ||
                                                            cm.Thursday || cm.Friday || cm.Saturday ? false : true;

                        int count = 0; //infinite loop protection x2!

                        //WHILE matchingStartDay is false (default false) AND the meeting time has at least one day of the week
                        //AND if we've hit a count of 7, that means we've already checked each day of the week and will never find one!
                        //exit while if we fail either of these conditions!
                        while ((!matchingStartDay && !meetingTimeWithoutDaysOfWeek) && count < 7)
                        {
                            switch (currentTime.DayOfWeek) //find which day of the week for this meeting
                            {
                            case DayOfWeek.Monday:
                                if (cm.Monday)
                                {
                                    matchingStartDay = true;
                                }
                                break;

                            case DayOfWeek.Tuesday:
                                if (cm.Tuesday)
                                {
                                    matchingStartDay = true;
                                }
                                break;

                            case DayOfWeek.Wednesday:
                                if (cm.Wednesday)
                                {
                                    matchingStartDay = true;
                                }
                                break;

                            case DayOfWeek.Thursday:
                                if (cm.Thursday)
                                {
                                    matchingStartDay = true;
                                }
                                break;

                            case DayOfWeek.Friday:
                                if (cm.Friday)
                                {
                                    matchingStartDay = true;
                                }
                                break;

                            case DayOfWeek.Saturday:
                                if (cm.Saturday)
                                {
                                    matchingStartDay = true;
                                }
                                break;

                            case DayOfWeek.Sunday:
                                if (cm.Sunday)
                                {
                                    matchingStartDay = true;
                                }
                                break;

                            default:
                                matchingStartDay = false;
                                break;
                            }

                            if (!matchingStartDay)
                            {
                                currentTime = new DateTime(currentTime.Year, currentTime.Month, currentTime.AddDays(1).Day,
                                                           evtStart.Hour, evtStart.Minute, evtStart.Second, DateTimeKind.Utc);
                            }
                            count++; //infinite loop protection x2! if we've reached 7 we've cycled all weekdays, so get us out of here!
                        }

                        //proceed only if there was a day of the week found for this course meeting time
                        if (!meetingTimeWithoutDaysOfWeek && matchingStartDay)
                        {
                            evt.Start        = new iCalDateTime(currentTime.UTCToCourse(ActiveCourseUser.AbstractCourseID));
                            evt.End          = new iCalDateTime(evtEnd.UTCToCourse(ActiveCourseUser.AbstractCourseID));
                            evt.LastModified = new iCalDateTime(DateTime.Now);
                            evt.Summary      = cm.Name;
                            evt.Location     = cm.Location;
                            evt.RecurrenceRules.Add(pattern);
                        }
                    }
                }

                //create the course breaks
                foreach (CourseBreak cb in course.CourseBreaks)
                {
                    DDay.iCal.Event evt      = courseCalendar.Create <DDay.iCal.Event>();
                    DateTime        evtStart = cb.StartDate.Date;
                    DateTime        evtEnd   = cb.EndDate.Date.AddDays(1);

                    evt.Summary      = cb.Name;
                    evt.Start        = new iCalDateTime(evtStart);
                    evt.End          = new iCalDateTime(evtEnd);
                    evt.LastModified = new iCalDateTime(DateTime.Now);
                }
            }//end if

            //add all the events to the calendar
            foreach (var e in events)
            {
                DDay.iCal.Event evt = courseCalendar.Create <DDay.iCal.Event>();

                evt.Start = new iCalDateTime(e.StartDate.UTCToCourse(ActiveCourseUser.AbstractCourseID));
                if (e.EndDate == null)
                {
                    evt.End = new iCalDateTime(e.StartDate.UTCToCourse(ActiveCourseUser.AbstractCourseID));
                    evt.End.AddMinutes(1);
                }
                else
                {
                    evt.End = new iCalDateTime(((DateTime)e.EndDate).UTCToCourse(ActiveCourseUser.AbstractCourseID));
                }

                evt.Summary = e.Title;
                if (e.Description != null)
                {
                    evt.Description = e.Description;
                }
            }

            // Create a serialization context and serializer factory.
            // These will be used to build the serializer for our object.
            ISerializationContext ctx     = new SerializationContext();
            ISerializerFactory    factory = new DDay.iCal.Serialization.iCalendar.SerializerFactory();
            // Get a serializer for our object
            IStringSerializer serializer = factory.Build(courseCalendar.GetType(), ctx) as IStringSerializer;

            string output = serializer.SerializeToString(courseCalendar);
            var    bytes  = Encoding.UTF8.GetBytes(output);

            SaveCourseCalendar(bytes, course.ID);
        }
Exemple #6
0
        public void SystemTimeZone2()
        {
            System.TimeZoneInfo tzi = System.TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time");
            Assert.IsNotNull(tzi);

            iCalendar iCal = new iCalendar();
            ITimeZone tz = iCal.AddTimeZone(tzi);
            Assert.IsNotNull(tz);

            iCalendarSerializer serializer = new iCalendarSerializer();
            serializer.Serialize(iCal, @"Calendars\Serialization\SystemTimeZone2.ics");

            iCalDateTime dt1 = new iCalDateTime(2003, 10, 26, 0, 59, 59, tz.TZID, iCal);
            iCalDateTime dt2 = new iCalDateTime(2003, 10, 26, 1, 0, 0, tz.TZID, iCal);
            TimeSpan result = dt2 - dt1;
            Assert.AreEqual(TimeSpan.FromHours(1) + TimeSpan.FromSeconds(1), result);

            dt1 = new iCalDateTime(2004, 4, 4, 1, 59, 59, tz.TZID, iCal);
            dt2 = new iCalDateTime(2004, 4, 4, 2, 0, 0, tz.TZID, iCal);
            result = dt2 - dt1;
            Assert.AreEqual(TimeSpan.FromHours(-1) + TimeSpan.FromSeconds(1), result);
        }
        /// <summary>
        ///     Generates the I calendar.
        /// </summary>
        /// <exception cref="System.ArgumentNullException">
        ///     eventEntity
        ///     or
        ///     inbox
        /// </exception>
        private static iCalendar GenerateICalendar(Appointment appointment, string emailAddress)
        {
            if (appointment == null)
            {
                throw new ArgumentNullException("eventEntity");
            }

            if (string.IsNullOrEmpty(emailAddress))
            {
                throw new ArgumentNullException("emailAddress");
            }

            try
            {
                /////
                // Calendar object
                /////
                var calendar      = new iCalendar( );
                var calendarEvent = calendar.Create <iCalEvent>( );

                ICalUidContainer iCalUidContainer = appointment.ICalAppt.CalendarId;

                string uid = null;

                /////
                // If there exists a reference to a previously sent message, obtain it and use the iCal UID from it.
                // Note* This is required to ensure proposed updates modify the existing calendar entry and no create a new one.
                /////
                if (iCalUidContainer != null)
                {
                    uid = iCalUidContainer.ICalUid;

                    if (!string.IsNullOrEmpty(uid))
                    {
                        calendarEvent.Uid = uid;
                    }
                }

                /////
                // Create the time zone object.
                /////
                TimeZoneInfo tzi = CreateTimezone( );
                ITimeZone    tz  = null;

                if (tzi != null)
                {
                    tz = calendar.AddTimeZone(tzi);
                }

                /////
                // Start time.
                /////
                if (appointment.EventStart != null)
                {
                    calendarEvent.Start = tz != null ? new iCalDateTime(ConvertDateTime(appointment.EventStart.Value, TimeZoneInfo.Utc, tzi), tz.TzId) : new iCalDateTime(appointment.EventStart.Value);
                }

                /////
                // End time.
                /////
                if (appointment.EventEnd != null)
                {
                    calendarEvent.End = tz != null ? new iCalDateTime(ConvertDateTime(appointment.EventEnd.Value, TimeZoneInfo.Utc, tzi), tz.TzId) : new iCalDateTime(appointment.EventEnd.Value);
                }

                /////
                // All day event.
                /////
                if (appointment.EventIsAllDay != null)
                {
                    calendarEvent.IsAllDay = appointment.EventIsAllDay.Value;
                }

                /////
                // Location.
                /////
                if (appointment.EventLocation != null)
                {
                    calendarEvent.Location = appointment.EventLocation;
                }

                /////
                // Priority. (CUA defined)
                /////
                if (appointment.EventEmailPriority != null)
                {
                    EventEmailPriorityEnum eventEmailPriorityStatus = appointment.EventEmailPriority;

                    switch (eventEmailPriorityStatus.Alias)
                    {
                    case "core:lowPriority":
                        calendarEvent.Priority = 9;
                        break;

                    case "core:normalPriority":
                        calendarEvent.Priority = 5;
                        break;

                    case "core:highPriority":
                        calendarEvent.Priority = 1;
                        break;
                    }
                }

                /////
                // Summary.
                /////
                calendarEvent.Summary = !string.IsNullOrEmpty(appointment.Name) ? string.Format("{0} - {1}", appointment.Name, GlobalStrings.DefaultICalSummary) : GlobalStrings.DefaultICalSummary;

                /////
                // Status.
                /////
                if (appointment.EventStatus != null)
                {
                    EventStatusEnum eventStatusEnum = appointment.EventStatus;

                    switch (eventStatusEnum.Alias)
                    {
                    case "core:eventStatusTentative":
                        calendarEvent.Status = Scheduling.iCalendar.EventStatus.Tentative;
                        calendar.Method      = Methods.Request;
                        break;

                    case "core:eventStatusConfirmed":
                        calendarEvent.Status = Scheduling.iCalendar.EventStatus.Confirmed;
                        calendar.Method      = Methods.Publish;
                        break;

                    case "core:eventStatusCancelled":

                        /////
                        // If there is no previous iCal UID, ignore this since it is invalid.
                        /////
                        if (uid == null)
                        {
                            return(null);
                        }

                        calendarEvent.Status = Scheduling.iCalendar.EventStatus.Cancelled;
                        calendar.Method      = Methods.Cancel;
                        break;
                    }
                }
                else
                {
                    /////
                    // New and Updated events must be Requests.
                    /////
                    calendar.Method = Methods.Request;
                }

                /////
                // Process the organizer.
                /////
                ProcessOrganizer(calendarEvent, emailAddress);

                /////
                // Process attendees.
                /////
                ProcessAttendees(calendarEvent, appointment);

                // if there are no attendees there is no iCal appointment
                if (calendarEvent.Attendees.Count <= 0)
                {
                    return(null);
                }

                if (appointment.ICalAppt.CalendarId == null || appointment.ICalAppt.CalendarId.ICalUid != calendarEvent.Uid)
                {
                    /////
                    // Create an iCal UID Container.
                    /////
                    var container = new ICalUidContainer
                    {
                        ICalUid            = calendarEvent.Uid,
                        CalendarEventEmail = appointment.ICalAppt
                    };

                    /////
                    // Store the iCal UID in the email message so we can correlate any new proposed times.
                    /////

                    /////
                    // Save the container.
                    /////
                    container.Save( );
                }

                return(calendar);
            }
            catch (Exception exc)
            {
                EventLog.Application.WriteError("Failed to generate iCalendar attachment." + exc);
            }

            return(null);
        }
Exemple #8
0
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            if (!Page.User.Identity.IsAuthenticated)
            {
                throw new MyFlightbookException("Unauthorized!");
            }

            int idClub = util.GetIntParam(Request, "c", 0);
            if (idClub == 0)
            {
                throw new MyFlightbookException("Invalid club");
            }

            Club c = Club.ClubWithID(idClub);

            if (c == null)
            {
                throw new MyFlightbookException(String.Format(System.Globalization.CultureInfo.InvariantCulture, "Invalid club: {0}", idClub));
            }

            string   szIDs  = util.GetStringParam(Request, "sid");
            string[] rgSIDs = szIDs.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            if (rgSIDs.Length == 0)
            {
                throw new MyFlightbookException("No scheduled events to download specified");
            }

            bool fIsAdmin = c.HasAdmin(Page.User.Identity.Name);

            using (iCalendar ic = new iCalendar())
            {
                ic.AddTimeZone(c.TimeZone);

                string szTitle = string.Empty;

                foreach (string sid in rgSIDs)
                {
                    ScheduledEvent se = ScheduledEvent.AppointmentByID(sid, c.TimeZone);

                    if (se == null)
                    {
                        throw new MyFlightbookException(String.Format(System.Globalization.CultureInfo.InvariantCulture, "Invalid scheduled event ID: {0}", sid));
                    }

                    if (!fIsAdmin && Page.User.Identity.Name.CompareOrdinal(se.OwningUser) != 0)
                    {
                        throw new MyFlightbookException("Attempt to download appointment that you don't own!");
                    }

                    ClubAircraft ca = c.MemberAircraft.FirstOrDefault(ca2 => ca2.AircraftID.ToString(System.Globalization.CultureInfo.InvariantCulture).CompareOrdinal(se.ResourceID) == 0);

                    Event ev = ic.Create <Event>();
                    ev.UID           = se.ID;
                    ev.IsAllDay      = false;
                    ev.Start         = new iCalDateTime(se.StartUtc, TimeZoneInfo.Utc.Id);
                    ev.End           = new iCalDateTime(se.EndUtc, TimeZoneInfo.Utc.Id);
                    ev.Start.HasTime = ev.End.HasTime = true;   // has time is false if the ultimate time is midnight.
                    szTitle          = ev.Description = ev.Summary = String.Format(System.Globalization.CultureInfo.CurrentCulture, "{0}{1}", ca == null ? string.Empty : String.Format(System.Globalization.CultureInfo.CurrentCulture, "{0} - ", ca.DisplayTailnumber), se.Body);
                    ev.Location      = c.HomeAirport == null ? c.HomeAirportCode : String.Format(System.Globalization.CultureInfo.CurrentCulture, "{0} - {1}", c.HomeAirportCode, c.HomeAirport.Name);

                    Alarm a = new Alarm();
                    a.Action           = AlarmAction.Display;
                    a.Description      = ev.Summary;
                    a.Trigger          = new Trigger();
                    a.Trigger.DateTime = ev.Start.AddMinutes(-30);
                    ev.Alarms.Add(a);

                    ic.Method = "PUBLISH";
                }

                iCalendarSerializer s = new iCalendarSerializer();

                string output = s.SerializeToString(ic);
                Page.Response.Clear();
                Page.Response.ContentType = "text/calendar";
                Response.AddHeader("Content-Disposition", String.Format(System.Globalization.CultureInfo.InvariantCulture, "inline;filename={0}", Branding.ReBrand(String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}appt.ics", szTitle)).Replace(" ", "-")));
                Response.Write(output);
                Response.Flush();
                Response.End();
            }
        }
    }