示例#1
0
        protected IDateTime ConvertToIDateTime(DateTime dt, IDateTime referenceDate)
        {
            IDateTime newDt = new CalDateTime(dt, referenceDate.TzId);

            newDt.AssociateWith(referenceDate);
            return(newDt);
        }
 public void CalDateTime_Tests(CalDateTime incomingDt, CalDateTime expectedDt)
 {
     Assert.AreEqual(incomingDt.Value, expectedDt.Value);
     Assert.AreEqual(incomingDt.GetHashCode(), expectedDt.GetHashCode());
     Assert.AreEqual(incomingDt.TzId, expectedDt.TzId);
     Assert.IsTrue(incomingDt.Equals(expectedDt));
 }
示例#3
0
        public static IEnumerable <ITestCaseData> AsDateTimeOffsetTestCases()
        {
            const string nyTzId     = "America/New_York";
            var          summerDate = DateTime.Parse("2018-05-15T11:00");

            var nySummerOffset = TimeSpan.FromHours(-4);
            var nySummer       = new CalDateTime(summerDate, nyTzId);

            yield return(new TestCaseData(nySummer)
                         .SetName("NY Summer DateTime returns DateTimeOffset with UTC-4")
                         .Returns(new DateTimeOffset(summerDate, nySummerOffset)));

            var utc = new CalDateTime(summerDate, "UTC");

            yield return(new TestCaseData(utc)
                         .SetName("UTC summer DateTime returns a DateTimeOffset with UTC-0")
                         .Returns(new DateTimeOffset(summerDate, TimeSpan.Zero)));

            var convertedToNySummer = new CalDateTime(summerDate, "UTC");

            convertedToNySummer.TzId = nyTzId;
            yield return(new TestCaseData(convertedToNySummer)
                         .SetName("Summer UTC DateTime converted to NY time zone by setting TzId returns a DateTimeOffset with UTC-4")
                         .Returns(new DateTimeOffset(summerDate, nySummerOffset)));

            var noTz = new CalDateTime(summerDate);
            var currentSystemOffset = TimeZoneInfo.Local.GetUtcOffset(summerDate);

            yield return(new TestCaseData(noTz)
                         .SetName($"Summer DateTime with no time zone information returns the system-local's UTC offset ({currentSystemOffset})")
                         .Returns(new DateTimeOffset(summerDate, currentSystemOffset)));
        }
示例#4
0
        public void Google1()
        {
            var tzId = "Europe/Berlin";
            var iCal = SimpleDeserializer.Default.Deserialize(new StringReader(IcsFiles.Google1)).Cast <Calendar>().Single();
            var evt  = iCal.Events["*****@*****.**"];

            Assert.IsNotNull(evt);

            IDateTime dtStart     = new CalDateTime(2006, 12, 18, tzId);
            IDateTime dtEnd       = new CalDateTime(2006, 12, 23, tzId);
            var       occurrences = iCal.GetOccurrences(dtStart, dtEnd).OrderBy(o => o.Period.StartTime).ToList();

            var dateTimes = new[]
            {
                new CalDateTime(2006, 12, 18, 7, 0, 0, tzId),
                new CalDateTime(2006, 12, 19, 7, 0, 0, tzId),
                new CalDateTime(2006, 12, 20, 7, 0, 0, tzId),
                new CalDateTime(2006, 12, 21, 7, 0, 0, tzId),
                new CalDateTime(2006, 12, 22, 7, 0, 0, tzId)
            };

            for (var i = 0; i < dateTimes.Length; i++)
            {
                Assert.AreEqual(dateTimes[i], occurrences[i].Period.StartTime, "Event should occur at " + dateTimes[i]);
            }

            Assert.AreEqual(dateTimes.Length, occurrences.Count, "There should be exactly " + dateTimes.Length + " occurrences; there were " + occurrences.Count);
        }
        public static ICalCalendar ParseICalendarFile(string filePath, string countryCode, string countryName)
        {
            ICalCalendar result = new ICalCalendar(countryCode, countryName);

            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException(string.Format("Could not find {0}.", filePath));
            }
            if (Path.GetExtension(filePath).Trim().ToLower() != ICALENDAR_FILE_EXTENSION)
            {
                throw new ArgumentException(string.Format(
                                                "Invalid file extension on iCalendar file. Expected file extension of '{0}'.",
                                                ICALENDAR_FILE_EXTENSION));
            }
            string   calendarText = File.ReadAllText(filePath);
            Calendar calendar     = Calendar.Load(calendarText);

            foreach (CalendarEvent e in calendar.Events)
            {
                if (e.Class.ToLower() == PUBLIC_HOLIDAY_EVENT_CLASS_NAME) //This is a public holiday event.
                {
                    string      name        = e.Name;
                    string      eventName   = e.Summary;
                    string      description = e.Description;
                    CalDateTime startDate   = e.Start as CalDateTime;
                    CalDateTime endDate     = e.End as CalDateTime;
                    if (!startDate.HasDate || !endDate.HasDate)
                    {
                        continue;
                    }
                    result.PublicHolidays.Add(new ICalPublicHoliday(eventName, startDate.Year, startDate.Month, startDate.Day));
                }
            }
            return(result);
        }
示例#6
0
        public void Converting_local_time_object_to_utc_should_give_expected_result()
        {
            string timezoneId = "Europe/Berlin";
            var    lt         = DateTime.UtcNow;
            var    dt         = new CalDateTime(lt, timezoneId); // Note the UTC clock is carried into the local timezone!
            var    utc        = dt.AsUtc;

            Assert.IsTrue(utc.Hour < dt.Hour, "UTC is expected to be smaller then local time!");
        }
示例#7
0
        public void CalDateTimeTests()
        {
            var nowLocal = DateTime.Now;
            var nowUtc   = nowLocal.ToUniversalTime();

            var asLocal = new CalDateTime(nowLocal, "America/New_York");
            var asUtc   = new CalDateTime(nowUtc, "UTC");

            Assert.AreNotEqual(asLocal, asUtc);
        }
        public static IEnumerable <ITestCaseData> CalDateTime_TestCases()
        {
            var nowCalDt = new CalDateTime(_nowTime);

            yield return(new TestCaseData(nowCalDt, new CalDateTime(_nowTime)).SetName("Now, no time zone"));

            var nowCalDtWithTz = new CalDateTime(_nowTime, _someTz);

            yield return(new TestCaseData(nowCalDtWithTz, new CalDateTime(_nowTime, _someTz)).SetName("Now, with time zone"));
        }
示例#9
0
        public override async Task <IActionResult> GetAsync()
        {
            var asyncPatientAppointments = await base.GetAsync();

            var patientAppointments = (List <PatientAppointment>)((ObjectResult)asyncPatientAppointments).Value;

            patientAppointments.ForEach(p =>
            {
                if (!string.IsNullOrEmpty(p.RecurrenceRule))
                {
                    RecurrencePattern pattern = new RecurrencePattern(p.RecurrenceRule);
                    pattern.RestrictionType   = RecurrenceRestrictionType.NoRestriction;

                    var us = new CultureInfo("en-US");

                    var startDate = new CalDateTime(p.StartDateTime, "UTC");
                    var fromDate  = new CalDateTime(p.StartDateTime, "UTC");
                    var toDate    = new CalDateTime();
                    if (pattern.Until != null && pattern.Until != DateTime.MinValue)
                    {
                        toDate = new CalDateTime(pattern.Until, "UTC");
                    }
                    else if (pattern.Count != 0 && pattern.Count != Int32.MinValue)
                    {
                        toDate = new CalDateTime(p.EndDateTime.AddDays(pattern.Interval * pattern.Count), "UTC");
                    }
                    else
                    {
                        toDate = new CalDateTime(p.EndDateTime.AddYears(2), "UTC");
                    }

                    var evaluator = pattern.GetService(typeof(IEvaluator)) as IEvaluator;

                    var tt = DateUtil.SimpleDateTimeToMatch(toDate, startDate);

                    p.Occurrences = evaluator.Evaluate(
                        startDate,
                        DateUtil.SimpleDateTimeToMatch(fromDate, startDate),
                        DateUtil.SimpleDateTimeToMatch(toDate, startDate),
                        true)
                                    .OrderBy(o => o.StartTime)
                                    .ToList();
                    var endDate = new CalDateTime(p.EndDateTime, "UTC");
                    TimeSpan t  = p.EndDateTime - p.StartDateTime;
                    p.Occurrences.ForEach(m => m.Duration = t);
                    p.RecurrencePattern = pattern;
                }
            });

            ((ObjectResult)asyncPatientAppointments).Value = patientAppointments;

            return(asyncPatientAppointments);
        }
        private Period CreatePeriod(DateTime dt, IDateTime referenceDate)
        {
            // Turn each resulting date/time into an IDateTime and associate it
            // with the reference date.
            IDateTime newDt = new CalDateTime(dt, referenceDate.TzId);

            // NOTE: fixes bug #2938007 - hasTime missing
            newDt.HasTime = referenceDate.HasTime;

            newDt.AssociateWith(referenceDate);

            // Create a period from the new date/time.
            return(new Period(newDt));
        }
示例#11
0
        private void TestComparison(Func <CalDateTime, IDateTime, bool> calOp, Func <int?, int?, bool> intOp)
        {
            int?intSome    = 1;
            int?intGreater = 2;

            var dtSome    = new CalDateTime(2018, 1, 1);
            var dtGreater = new CalDateTime(2019, 1, 1);

            Assert.AreEqual(intOp(null, null), calOp(null, null));
            Assert.AreEqual(intOp(null, intSome), calOp(null, dtSome));
            Assert.AreEqual(intOp(intSome, null), calOp(dtSome, null));
            Assert.AreEqual(intOp(intSome, intSome), calOp(dtSome, dtSome));
            Assert.AreEqual(intOp(intSome, intGreater), calOp(dtSome, dtGreater));
            Assert.AreEqual(intOp(intGreater, intSome), calOp(dtGreater, dtSome));
        }
示例#12
0
        /// <summary>
        /// Testing RecurrentExample (see comment there) against a provided DateTimeOffset,
        /// trying what operations must be done to ensure that the DateTimeOffset is converted
        /// to the time as of the TimeZone rather than get it 'as is' (this will enable us to read
        /// database DateTimeOffsets that has an offset that doesn't match the Event or user time zone but
        /// must be converted to that before calculate occurrences).
        /// </summary>
        /// <returns></returns>
        static string OffsetRecurrentExample(string tz)
        {
            // We have a DateTime with an attached Offset, so the equivalent UTC time must be the same
            // on any tested time zone for a time not in the DST range,
            // it just changes the local value displayed and the calculations
            // of occurrences regarding DST (has or not DST, different DST date change).
            // Midday at UTC saved on UTC
            //var now = new DateTimeOffset(2016, 1, 1, 12, 0, 0, new TimeSpan(0, 0, 0));
            // Midday at UTC saved at PST (America/Los_Angeles)
            // -- results must be the same as when saved as UTC with the corrected time, as opposite to
            // the RecurrentExample method
            var now   = new DateTimeOffset(2016, 1, 1, 4, 0, 0, new TimeSpan(-8, 0, 0));
            var later = now.AddHours(1);

            var rrule = new RecurrencePattern(FrequencyType.Monthly, 1)
            {
                Count = 12
            };

            var timezone = NodaTime.DateTimeZoneProviders.Tzdb.GetZoneOrNull(tz);
            var znow     = new NodaTime.ZonedDateTime(NodaTime.Instant.FromDateTimeOffset(now), timezone);
            var start    = new CalDateTime(znow.LocalDateTime.ToDateTimeUnspecified(), tz);

            //Console.WriteLine("timezone {0}, znow: {1}, start: {2}", timezone, znow, start);

            var e = new Event
            {
                DtStart         = start,
                Duration        = new TimeSpan(1, 0, 0),
                RecurrenceRules = new List <IRecurrencePattern> {
                    rrule
                },
            };

            var calendar = new Calendar();

            calendar.Events.Add(e);

            //var serializer = new CalendarSerializer(new SerializationContext());
            //return serializer.SerializeToString(calendar);

            var endSearch = new DateTime(2017, 1, 1, 12, 0, 0).ToUniversalTime();

            return(calendar.GetOccurrences(now.UtcDateTime, endSearch).Aggregate("", (ret, a) =>
            {
                return ret + a.Period.StartTime.AsUtc.ToString() + "\n";
            }));
        }
示例#13
0
        public void TestAlarm(string calendarString, List <IDateTime> dates, CalDateTime start, CalDateTime end)
        {
            var iCal = Calendar.LoadFromStream(new StringReader(calendarString))[0];

            ProgramTest.TestCal(iCal);
            var evt = iCal.Events.First();

            // Poll all alarms that occurred between Start and End
            var alarms = evt.PollAlarms(start, end);

            foreach (var alarm in alarms)
            {
                Assert.IsTrue(dates.Contains(alarm.DateTime), "Alarm triggers at " + alarm.Period.StartTime + ", but it should not.");
            }
            Assert.IsTrue(dates.Count == alarms.Count, "There were " + alarms.Count + " alarm occurrences; there should have been " + dates.Count + ".");
        }
示例#14
0
 private static void PopulateTimeZoneInfoRecurrenceDates(ITimeZoneInfo tzi, List <ZoneInterval> intervals, TimeSpan delta)
 {
     foreach (var interval in intervals)
     {
         var periodList = new PeriodList();
         var time       = interval.IsoLocalStart.ToDateTimeUnspecified();
         var date       = new CalDateTime(time).Add(delta) as CalDateTime;
         if (date == null)
         {
             continue;
         }
         date.HasTime = true;
         periodList.Add(date);
         tzi.RecurrenceDates.Add(periodList);
     }
 }
示例#15
0
        private void EnsureProperties()
        {
            if (string.IsNullOrEmpty(Uid))
            {
                // Create a new UID for the component
                Uid = Guid.NewGuid().ToString();
            }

            // NOTE: removed setting the 'CREATED' property here since it breaks serialization.
            // See https://sourceforge.net/projects/dday-ical/forums/forum/656447/topic/3754354
            if (DtStamp == null)
            {
                // icalendar RFC doesn't care about sub-second time resolution, so shave off everything smaller than seconds.
                var utcNow = DateTime.UtcNow.Truncate(TimeSpan.FromSeconds(1));
                DtStamp = new CalDateTime(utcNow, "UTC");
            }
        }
示例#16
0
        public void TestAlarm(string calendarString, List <IDateTime> dates, CalDateTime start, CalDateTime end)
        {
            var iCal = Calendar.LoadFromStream(new StringReader(calendarString))[0];

            ProgramTest.TestCal(iCal);
            var evt = iCal.Events.First();

            // Poll all alarms that occurred between Start and End
            var alarms = evt.PollAlarms(start, end);

            //Only compare the UTC values here, since we care about the time coordinate when the alarm fires, and nothing else
            foreach (var alarm in alarms.Select(a => a.DateTime.AsUtc))
            {
                Assert.IsTrue(dates.Select(d => d.AsUtc).Contains(alarm), "Alarm triggers at " + alarm + ", but it should not.");
            }
            Assert.IsTrue(dates.Count == alarms.Count, "There were " + alarms.Count + " alarm occurrences; there should have been " + dates.Count + ".");
        }
示例#17
0
        public void TestTzidChanges()
        {
            var someTime = DateTimeOffset.Parse("2018-05-21T11:35:00-04:00");

            var someDt = new CalDateTime(someTime.DateTime)
            {
                TzId = "America/New_York"
            };
            var firstUtc = someDt.AsUtc;

            Assert.AreEqual(someTime.UtcDateTime, firstUtc);

            someDt.TzId = "Europe/Berlin";
            var berlinUtc = someDt.AsUtc;

            Assert.AreNotEqual(firstUtc, berlinUtc);
        }
示例#18
0
        public void SkippedOccurrenceOnWeeklyPattern()
        {
            const int evaluationsCount = 1000;
            var       eventStart       = new CalDateTime(new DateTime(2016, 1, 1, 10, 0, 0, DateTimeKind.Utc));
            var       eventEnd         = new CalDateTime(new DateTime(2016, 1, 1, 11, 0, 0, DateTimeKind.Utc));
            var       vEvent           = new CalendarEvent
            {
                DtStart = eventStart,
                DtEnd   = eventEnd,
            };

            var pattern = new RecurrencePattern
            {
                Frequency = FrequencyType.Weekly,
                ByDay     = new List <WeekDay> {
                    new WeekDay(DayOfWeek.Friday)
                }
            };

            vEvent.RecurrenceRules.Add(pattern);
            var calendar = new Calendar();

            calendar.Events.Add(vEvent);

            var intervalStart = eventStart;
            var intervalEnd   = intervalStart.AddDays(7 * evaluationsCount);

            var occurrences = RecurrenceUtil.GetOccurrences(
                recurrable: vEvent,
                periodStart: intervalStart,
                periodEnd: intervalEnd,
                includeReferenceDateInResults: false);
            var occurrenceSet = new HashSet <IDateTime>(occurrences.Select(o => o.Period.StartTime));

            Assert.AreEqual(evaluationsCount, occurrenceSet.Count);

            for (var currentOccurrence = intervalStart; currentOccurrence.CompareTo(intervalEnd) < 0; currentOccurrence = (CalDateTime)currentOccurrence.AddDays(7))
            {
                var contains = occurrenceSet.Contains(currentOccurrence);
                Assert.IsTrue(contains, $"Collection does not contain {currentOccurrence}, but it is a {currentOccurrence.DayOfWeek}");
            }
        }
示例#19
0
        private void EnsureProperties()
        {
            if (string.IsNullOrEmpty(Uid))
            {
                // Create a new UID for the component
                Uid = Guid.NewGuid().ToString();
            }

            // NOTE: removed setting the 'CREATED' property here since it breaks serialization.
            // See https://sourceforge.net/projects/dday-ical/forums/forum/656447/topic/3754354
            if (DtStamp == null)
            {
                // Here, we don't simply set to DateTime.Now because DateTime.Now contains milliseconds, and
                // the iCalendar standard doesn't care at all about milliseconds.  Therefore, when comparing
                // two calendars, one generated, and one loaded from file, they may be functionally identical,
                // but be determined to be different due to millisecond differences.
                var now = DateTime.SpecifyKind(DateTime.Today.Add(DateTime.UtcNow.TimeOfDay), DateTimeKind.Utc);
                DtStamp = new CalDateTime(now);
            }
        }
示例#20
0
        public void WrongDurationTest()
        {
            var firstStart = new CalDateTime(DateTime.Parse("2016-01-01"));
            var firstEnd   = new CalDateTime(DateTime.Parse("2016-01-05"));
            var vEvent     = new Event
            {
                DtStart = firstStart,
                DtEnd   = firstEnd,
            };

            var secondStart = new CalDateTime(DateTime.Parse("2016-03-01"));
            var secondEnd   = new CalDateTime(DateTime.Parse("2016-03-05"));
            var vEvent2     = new Event
            {
                DtStart = secondStart,
                DtEnd   = secondEnd,
            };

            var calendar = new Calendar();

            calendar.Events.Add(vEvent);
            calendar.Events.Add(vEvent2);

            var searchStart = DateTime.Parse("2015-12-29");
            var searchEnd   = DateTime.Parse("2017-02-10");
            var occurrences = calendar.GetOccurrences(searchStart, searchEnd).OrderBy(o => o.Period.StartTime).ToList();

            var firstOccurrence = occurrences.First();
            var firstStartCopy  = firstStart.Copy <CalDateTime>();
            var firstEndCopy    = firstEnd.Copy <CalDateTime>();

            Assert.AreEqual(firstStartCopy, firstOccurrence.Period.StartTime);
            Assert.AreEqual(firstEndCopy, firstOccurrence.Period.EndTime);

            var secondOccurrence = occurrences.Last();
            var secondStartCopy  = secondStart.Copy <CalDateTime>();
            var secondEndCopy    = secondEnd.Copy <CalDateTime>();

            Assert.AreEqual(secondStartCopy, secondOccurrence.Period.StartTime);
            Assert.AreEqual(secondEndCopy, secondOccurrence.Period.EndTime);
        }
示例#21
0
        public void SkippedOccurrenceOnWeeklyPattern()
        {
            const int evaluationsCount = 1000;
            var       eventStart       = new CalDateTime(new DateTime(2016, 1, 1, 10, 0, 0, DateTimeKind.Utc));
            var       eventEnd         = new CalDateTime(new DateTime(2016, 1, 1, 11, 0, 0, DateTimeKind.Utc));
            var       vEvent           = new CalendarEvent
            {
                DtStart = eventStart,
                DtEnd   = eventEnd,
            };

            var pattern = new RecurrencePattern
            {
                Frequency = FrequencyType.Weekly,
                ByDay     = new List <WeekDay> {
                    new WeekDay(DayOfWeek.Friday)
                }
            };

            vEvent.RecurrenceRules.Add(pattern);
            var calendar = new Calendar();

            calendar.Events.Add(vEvent);

            var intervalStart = eventStart;
            var intervalEnd   = intervalStart.AddDays(7 * evaluationsCount);

            var occurrences = RecurrenceUtil.GetOccurrences(vEvent, intervalStart, intervalEnd, false)
                              .Select(o => o.Period.StartTime)
                              .OrderBy(dt => dt)
                              .ToList();

            Assert.AreEqual(evaluationsCount, occurrences.Count);

            for (var currentOccurrence = intervalStart.AsUtc; currentOccurrence.CompareTo(intervalEnd.AsUtc) < 0; currentOccurrence = currentOccurrence.AddDays(7))
            {
                Assert.IsTrue(occurrences.Contains(new CalDateTime(currentOccurrence)),
                              $"Collection does not contain {currentOccurrence}, but it is a {currentOccurrence.DayOfWeek}");
            }
        }
示例#22
0
        public static string GetDayTime(CalDateTime dateTime)
        {
            var result = $"{dateTime.Hour.ToString().PadLeft(2, '0')}{dateTime.Minute.ToString().PadLeft(2, '0')}";

            return(Convert.ToInt64(result).ToString());
        }
示例#23
0
        public static string GetDate(CalDateTime dateTime)
        {
            var result = $"{dateTime.Year.ToString().PadLeft(4, '0')}{dateTime.Month.ToString().PadLeft(2, '0')}{dateTime.Day.ToString().PadLeft(2, '0')}";

            return(Convert.ToInt64(result).ToString());
        }
        /// <summary>
        /// Creates the iCalendar object and populates it with events
        /// </summary>
        /// <param name="calendarProps">The calendar props.</param>
        /// <returns></returns>
        private Calendar CreateICalendar(CalendarProps calendarProps)
        {
            // Get a list of Rock Calendar Events filtered by calendarProps
            List <EventItem> eventItems = GetEventItems(calendarProps);

            // Create the iCalendar.
            // Allow ICal to create the VTimeZone object from the local time zone to ensure that we get the correct name and daylight saving offset.
            var icalendar = new Calendar();

            var vtz = VTimeZone.FromLocalTimeZone();

            icalendar.AddTimeZone(vtz);

            var timeZoneId = vtz.TzId;

            // Create each of the events for the calendar(s)
            foreach (EventItem eventItem in eventItems)
            {
                foreach (EventItemOccurrence occurrence in eventItem.EventItemOccurrences)
                {
                    if (occurrence.Schedule == null)
                    {
                        continue;
                    }

                    var serializer = new CalendarSerializer();
                    var ical       = (CalendarCollection)serializer.Deserialize(occurrence.Schedule.iCalendarContent.ToStreamReader());

                    foreach (var icalEvent in ical[0].Events)
                    {
                        // We get all of the schedule info from Schedule.iCalendarContent
                        var ievent = icalEvent.Copy <Ical.Net.Event>();

                        ievent.Summary  = !string.IsNullOrEmpty(eventItem.Name) ? eventItem.Name : string.Empty;
                        ievent.Location = !string.IsNullOrEmpty(occurrence.Location) ? occurrence.Location : string.Empty;

                        // Create the list of exceptions.
                        // Exceptions must meet RFC 5545 iCalendar specifications to be correctly processed by third-party calendar applications
                        // such as Microsoft Outlook and Google Calendar. Specifically, an exception must have exactly the same start time
                        // and time zone as the template event, and the time zone must be expressed as an IANA name.
                        // The most recent version of iCal.Net (v2.3.5) that supports .NET framework v4.5.2 has some inconsistencies in the
                        // iCalendar serialization process, so we need to force the Start, End and Exception dates to render in exactly the same format.
                        ievent.Start = new CalDateTime(icalEvent.Start.Value, timeZoneId);
                        ievent.Start.IsUniversalTime = false;

                        ievent.End = new CalDateTime(icalEvent.End.Value, timeZoneId);
                        ievent.End.IsUniversalTime = false;

                        var eventStartTime = new TimeSpan(ievent.DtStart.Hour, ievent.DtStart.Minute, ievent.DtStart.Second);

                        var newExceptionDatesList = new List <Ical.Net.Interfaces.DataTypes.IPeriodList>();

                        foreach (var exceptionDateList in ievent.ExceptionDates)
                        {
                            var newDateList = new PeriodList()
                            {
                                TzId = timeZoneId
                            };

                            foreach (var exceptionDate in exceptionDateList)
                            {
                                var newDateTime = exceptionDate.StartTime.HasTime ? exceptionDate.StartTime.Value : exceptionDate.StartTime.Value.Add(eventStartTime);

                                newDateTime = new DateTime(newDateTime.Year, newDateTime.Month, newDateTime.Day, newDateTime.Hour, newDateTime.Minute, newDateTime.Second, newDateTime.Millisecond, DateTimeKind.Local);

                                var newDate = new CalDateTime(newDateTime);
                                newDate.IsUniversalTime = false;

                                newDateList.Add(newDate);
                            }

                            newExceptionDatesList.Add(newDateList);
                        }

                        ievent.ExceptionDates = newExceptionDatesList;

                        // Rock has more descriptions than iCal so lets concatenate them
                        string description = CreateEventDescription(eventItem, occurrence);

                        // Don't set the description prop for outlook to force it to use the X-ALT-DESC property which can have markup.
                        if (interactionDeviceType != "Outlook")
                        {
                            ievent.Description = description.ConvertBrToCrLf()
                                                 .Replace("</P>", "")
                                                 .Replace("</p>", "")
                                                 .Replace("<P>", Environment.NewLine)
                                                 .Replace("<p>", Environment.NewLine)
                                                 .Replace("&nbsp;", " ")
                                                 .SanitizeHtml();
                        }

                        // HTML version of the description for outlook
                        ievent.AddProperty("X-ALT-DESC;FMTTYPE=text/html", "<html>" + description + "</html>");

                        // classification: "PUBLIC", "PRIVATE", "CONFIDENTIAL"
                        ievent.Class = "PUBLIC";

                        if (!string.IsNullOrEmpty(eventItem.DetailsUrl))
                        {
                            Uri result;
                            if (Uri.TryCreate(eventItem.DetailsUrl, UriKind.Absolute, out result))
                            {
                                ievent.Url = result;
                            }
                            else if (Uri.TryCreate("http://" + eventItem.DetailsUrl, UriKind.Absolute, out result))
                            {
                                ievent.Url = result;
                            }
                        }

                        // add contact info if it exists
                        if (occurrence.ContactPersonAlias != null)
                        {
                            ievent.Organizer            = new Organizer(string.Format("MAILTO:{0}", occurrence.ContactPersonAlias.Person.Email));
                            ievent.Organizer.CommonName = occurrence.ContactPersonAlias.Person.FullName;

                            // Outlook doesn't seems to use Contacts or Comments
                            string contactName  = !string.IsNullOrEmpty(occurrence.ContactPersonAlias.Person.FullName) ? "Name: " + occurrence.ContactPersonAlias.Person.FullName : string.Empty;
                            string contactEmail = !string.IsNullOrEmpty(occurrence.ContactEmail) ? ", Email: " + occurrence.ContactEmail : string.Empty;
                            string contactPhone = !string.IsNullOrEmpty(occurrence.ContactPhone) ? ", Phone: " + occurrence.ContactPhone : string.Empty;
                            string contactInfo  = contactName + contactEmail + contactPhone;

                            ievent.Contacts.Add(contactInfo);
                            ievent.Comments.Add(contactInfo);
                        }

                        // TODO: categories - comma delimited list of whatever, might use audience
                        foreach (var a in eventItem.EventItemAudiences)
                        {
                            ievent.Categories.Add(a.DefinedValue.Value);
                        }

                        //// No attachments for now.
                        ////if ( eventItem.PhotoId != null )
                        ////{
                        ////    // The DDay Attachment obj doesn't allow you to name the attachment. Nice huh? So just add prop manually...
                        ////    ievent.AddProperty( "ATTACH;VALUE=BINARY;ENCODING=BASE64;X-FILENAME=\"" + eventItem.Photo.FileName + "\"", Convert.ToBase64String( eventItem.Photo.ContentStream.ReadBytesToEnd().ToArray() ) );
                        ////}

                        icalendar.Events.Add(ievent);
                    }
                }
            }

            return(icalendar);
        }
示例#25
0
 public DateTimeOffset AsDateTimeOffsetTests(CalDateTime incoming)
 => incoming.AsDateTimeOffset;
示例#26
0
        public override string SerializeToString(object obj)
        {
            var recur   = obj as IRecurrencePattern;
            var factory = GetService <ISerializerFactory>();

            if (recur == null || factory == null)
            {
                return(null);
            }

            // Push the recurrence pattern onto the serialization stack
            SerializationContext.Push(recur);
            var values = new List <string>(16)
            {
                "FREQ=" + Enum.GetName(typeof(FrequencyType), recur.Frequency).ToUpper()
            };


            //-- FROM RFC2445 --
            //The INTERVAL rule part contains a positive integer representing how
            //often the recurrence rule repeats. The default value is "1", meaning
            //every second for a SECONDLY rule, or every minute for a MINUTELY
            //rule, every hour for an HOURLY rule, every day for a DAILY rule,
            //every week for a WEEKLY rule, every month for a MONTHLY rule and
            //every year for a YEARLY rule.
            var interval = recur.Interval;

            if (interval == int.MinValue)
            {
                interval = 1;
            }

            if (interval != 1)
            {
                values.Add("INTERVAL=" + interval);
            }

            if (recur.Until != DateTime.MinValue)
            {
                var serializer = factory.Build(typeof(IDateTime), SerializationContext) as IStringSerializer;
                if (serializer != null)
                {
                    IDateTime until = new CalDateTime(recur.Until);
                    until.HasTime = true;
                    values.Add("UNTIL=" + serializer.SerializeToString(until));
                }
            }

            if (recur.FirstDayOfWeek != DayOfWeek.Monday)
            {
                values.Add("WKST=" + Enum.GetName(typeof(DayOfWeek), recur.FirstDayOfWeek).ToUpper().Substring(0, 2));
            }

            if (recur.Count != int.MinValue)
            {
                values.Add("COUNT=" + recur.Count);
            }

            if (recur.ByDay.Count > 0)
            {
                var bydayValues = new List <string>(128);

                var serializer = factory.Build(typeof(IWeekDay), SerializationContext) as IStringSerializer;
                if (serializer != null)
                {
                    bydayValues.AddRange(recur.ByDay.Select(byday => serializer.SerializeToString(byday)));
                }

                values.Add("BYDAY=" + string.Join(",", bydayValues.ToArray()));
            }

            SerializeByValue(values, recur.ByHour, "BYHOUR");
            SerializeByValue(values, recur.ByMinute, "BYMINUTE");
            SerializeByValue(values, recur.ByMonth, "BYMONTH");
            SerializeByValue(values, recur.ByMonthDay, "BYMONTHDAY");
            SerializeByValue(values, recur.BySecond, "BYSECOND");
            SerializeByValue(values, recur.BySetPosition, "BYSETPOS");
            SerializeByValue(values, recur.ByWeekNo, "BYWEEKNO");
            SerializeByValue(values, recur.ByYearDay, "BYYEARDAY");

            // Pop the recurrence pattern off the serialization stack
            SerializationContext.Pop();

            return(Encode(recur, string.Join(";", values.ToArray())));
        }
示例#27
0
        public Task <byte[]> GeneratorAsync(CalendarEventCollection events)
        {
            var calendar = new Calendar();

            foreach (var levent in events)
            {
                CalDateTime calStart = levent.IsWholeDay
                    ? new CalDateTime(levent.Begin.Year, levent.Begin.Month, levent.Begin.Day)
                    : new CalDateTime(levent.Begin.ToUniversalTime());

                CalDateTime calEnd = !levent.End.HasValue
                    ? calStart
                    : levent.IsWholeDay
                    ? new CalDateTime(levent.End.Value.Year, levent.End.Value.Month, levent.End.Value.Day)
                    : new CalDateTime(levent.End.Value.ToUniversalTime());

                if (levent.IsWholeDay)
                {
                    calStart.HasDate = true;
                    calStart.HasTime = false;

                    calEnd.HasDate = true;
                    calEnd.HasTime = false;

                    //https://github.com/toosean/ChinaPublicCalendar/issues/9
                    //非常感谢 JarmoHu 指正
                    calEnd = (CalDateTime)calEnd.AddDays(1);
                }

                using (var sha1 = SHA1.Create())
                {
                    byte[] titleBytes  = UTF8Encoding.UTF8.GetBytes(levent.Title);
                    byte[] hashMessage = sha1.ComputeHash(titleBytes);
                    string uid         = BitConverter.ToString(hashMessage).Replace("-", "").ToLower();

                    var revent = new Ical.Net.CalendarComponents.CalendarEvent()
                    {
                        Uid         = uid,
                        DtStamp     = calStart,
                        Start       = calStart,
                        End         = calEnd,
                        Summary     = levent.Title,
                        Description = levent.Description,
                        IsAllDay    = levent.IsWholeDay
                    };

                    calendar.Events.Add(revent);
                }
            }

            //for Google Calendar
            if (events.Name != null)
            {
                calendar.AddProperty("X-WR-CALNAME", events.Name);
            }
            calendar.Method = "PUBLISH";

            using (var memoryStream = new MemoryStream())
            {
                var serializer = new CalendarSerializer();
                serializer.Serialize(calendar, memoryStream, new UTF8Encoding(false));

                return(Task.FromResult(memoryStream.ToArray()));
            }
        }
示例#28
0
        private async Task <RocketMessage> GetMessageAsync(DateTime eventDate)
        {
            var calendars = await FetchCalendarsAsync();

            IDateTime date = new CalDateTime(eventDate);

            var events = calendars.SelectMany(x => x.Events)
                         .Where(c => c.DtStart.Equals(date))
                         .ToList();

            if (!events.Any())
            {
                return(null);
            }

            var message = new RocketMessage
            {
                UserName = _appSettings.UserName,
                IconUrl  = _appSettings.IconUrl,
                Text     = _appSettings.Text
                           .Replace(MacroVariables.Date, eventDate.Date.ToString("D"))
            };

            foreach (var item in events)
            {
                var url      = item.Url.ToString();
                var imageUrl = await GetImageUrlAsync(url);

                if (string.IsNullOrWhiteSpace(imageUrl))
                {
                    imageUrl = _appSettings.DefaultImage;
                }

                var attachment = new RocketAttachment
                {
                    Title       = item.Summary,
                    TitleLink   = url,
                    MessageLink = url,
                    ImageUrl    = imageUrl,
                    Text        = Regex.Replace(item.Description, "\n{2,}", "\n")
                                  .Replace(_appSettings.SignatureForRemoval, string.Empty)
                                  .Trim(),
                    Fields = new List <RocketField>
                    {
                        new RocketField
                        {
                            Title = item.Summary,
                            Value = $"[Read]({url}) more about the holiday."
                        },
                        new RocketField
                        {
                            Title = item.Calendar.Properties["X-WR-CALNAME"].Value.ToString(),
                            Value = $"[Download]({item.Calendar.Properties["Url"].Value}) the calendar."
                        }
                    }
                };

                message.Attachments.Add(attachment);
            }

            return(message);
        }
示例#29
0
        public CalDateTime GetStartTime(DateTime date, string timezoneId)
        {
            var cdt = new CalDateTime(date.Year, date.Month, date.Day, Begin.Hours, Begin.Minutes, Begin.Seconds, timezoneId);

            return(new CalDateTime(cdt.AsUtc));
        }