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); }
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); }
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); }
/// <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); }
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(); } } }