public TimeCalculation(Date_Time StartDate, Date_Time EndDate, Recur Recur) { this.StartDate = StartDate; this.EndDate = EndDate; this.Recur = Recur; Year = StartDate.Value.Year; Month = StartDate.Value.Month; Day = StartDate.Value.Day; Hour = StartDate.Value.Hour; Minute = StartDate.Value.Minute; Second = StartDate.Value.Second; YearDays = new List <int>(Recur.ByYearDay); ByDays = new List <DaySpecifier>(Recur.ByDay); Months = new List <int>(Recur.ByMonth); Days = new List <int>(Recur.ByMonthDay); Hours = new List <int>(Recur.ByHour); Minutes = new List <int>(Recur.ByMinute); Seconds = new List <int>(Recur.BySecond); DateTimes = new List <Date_Time>(); // Only check what months and days are possible for // the week's period of time we're evaluating // NOTE: fixes RRULE10 evaluation if (Recur.Frequency == FrequencyType.WEEKLY) { if (Months.Count == 0) { Months.Add(StartDate.Value.Month); if (StartDate.Value.Month != EndDate.Value.Month) { Months.Add(EndDate.Value.Month); } } if (Days.Count == 0) { DateTime dt = StartDate.Value; while (dt < EndDate.Value) { Days.Add(dt.Day); dt = dt.AddDays(1); } Days.Add(EndDate.Value.Day); } } else { if (Months.Count == 0) { Months.AddRange(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }); } if (Days.Count == 0) { Days.AddRange(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }); } } }
public override bool Equals(object obj) { if (obj is Recur) { Recur r = (Recur)obj; if (!ArrayEquals(r.ByDay.ToArray(), ByDay.ToArray()) || !ArrayEquals(r.ByHour.ToArray(), ByHour.ToArray()) || !ArrayEquals(r.ByMinute.ToArray(), ByMinute.ToArray()) || !ArrayEquals(r.ByMonth.ToArray(), ByMonth.ToArray()) || !ArrayEquals(r.ByMonthDay.ToArray(), ByMonthDay.ToArray()) || !ArrayEquals(r.BySecond.ToArray(), BySecond.ToArray()) || !ArrayEquals(r.BySetPos.ToArray(), BySetPos.ToArray()) || !ArrayEquals(r.ByWeekNo.ToArray(), ByWeekNo.ToArray()) || !ArrayEquals(r.ByYearDay.ToArray(), ByYearDay.ToArray())) { return(false); } if (r.Count != Count) { return(false); } if (r.Frequency != Frequency) { return(false); } if (r.Interval != Interval && // MinValue and 1 are treated as identical for Interval ((r.Interval != int.MinValue && r.Interval != 1) || (Interval != int.MinValue && Interval != 1))) { return(false); } if (r.Until != null) { if (!r.Until.Equals(Until)) { return(false); } } else if (Until != null) { return(false); } if (r.Wkst != Wkst) { return(false); } return(true); } return(base.Equals(obj)); }
public static Date_Time AddFrequency(Recur.FrequencyType frequency, Date_Time dt, int interval) { switch (frequency) { case Recur.FrequencyType.YEARLY: return dt.AddYears(interval); case Recur.FrequencyType.MONTHLY: return dt.AddMonths(interval); case Recur.FrequencyType.WEEKLY: return dt.AddDays(interval * 7); case Recur.FrequencyType.DAILY: return dt.AddDays(interval); case Recur.FrequencyType.HOURLY: return dt.AddHours(interval); case Recur.FrequencyType.MINUTELY: return dt.AddMinutes(interval); case Recur.FrequencyType.SECONDLY: return dt.AddSeconds(interval); default: return dt; } }
public static long DateDiff(Recur.FrequencyType frequency, Date_Time dt1, Date_Time dt2, DayOfWeek firstDayOfWeek) { if (frequency == Recur.FrequencyType.YEARLY) return dt2.Year - dt1.Year; if (frequency == Recur.FrequencyType.MONTHLY) return (dt2.Month - dt1.Month) + (12 * (dt2.Year - dt1.Year)); if (frequency == Recur.FrequencyType.WEEKLY) { // Get the week of year of the time frame we want to calculate int firstEvalWeek = _Calendar.GetWeekOfYear(dt2.Value, System.Globalization.CalendarWeekRule.FirstFourDayWeek, firstDayOfWeek); // Count backwards in years, calculating how many weeks' difference we have between // first and second dates Date_Time evalDate = dt2.Copy(); while (evalDate.Year > dt1.Year) { firstEvalWeek += _Calendar.GetWeekOfYear(new DateTime(evalDate.Year - 1, 12, 31), System.Globalization.CalendarWeekRule.FirstFourDayWeek, firstDayOfWeek); evalDate = evalDate.AddYears(-1); } // Determine the difference, in weeks, between the start date and the evaluation period. int startWeek = _Calendar.GetWeekOfYear(dt1.Value, System.Globalization.CalendarWeekRule.FirstFourDayWeek, firstDayOfWeek); return firstEvalWeek - startWeek; } TimeSpan ts = dt2 - dt1; if (frequency == Recur.FrequencyType.DAILY) return Round(ts.TotalDays); if (frequency == Recur.FrequencyType.HOURLY) return Round(ts.TotalHours); if (frequency == Recur.FrequencyType.MINUTELY) return Round(ts.TotalMinutes); if (frequency == Recur.FrequencyType.SECONDLY) return Round(ts.TotalSeconds); return 0; }
public override bool TryParse(string value, ref object obj) { DaySpecifier bd = (DaySpecifier)obj; Match bdMatch = Regex.Match(value, @"(\+|-)?(\d{1,2})?(\w{2})"); if (bdMatch.Success) { if (bdMatch.Groups[2].Success) { bd.Num = Convert.ToInt32(bdMatch.Groups[2].Value); if (bdMatch.Groups[1].Success && bdMatch.Groups[1].Value.Contains("-")) { bd.Num *= -1; } } bd.DayOfWeek = Recur.GetDayOfWeek(bdMatch.Groups[3].Value); return(true); } return(false); }
public override void CopyFrom(object obj) { if (obj is Recur) { Recur r = (Recur)obj; Frequency = r.Frequency; Until = r.Until; Count = r.Count; Interval = r.Interval; BySecond = new ArrayList(r.BySecond); ByMinute = new ArrayList(r.ByMinute); ByHour = new ArrayList(r.ByHour); ByDay = new ArrayList(r.ByDay); ByMonthDay = new ArrayList(r.ByMonthDay); ByYearDay = new ArrayList(r.ByYearDay); ByWeekNo = new ArrayList(r.ByWeekNo); ByMonth = new ArrayList(r.ByMonth); BySetPos = new ArrayList(r.BySetPos); Wkst = r.Wkst; } }
public RecurSerializer(Recur recur) : base(recur) { this.m_Recur = recur; }
public RecurSerializer(DDay.iCal.DataTypes.Recur recur) : base(recur) { this.m_Recur = recur; }
public List<Date_Time> Evaluate(Date_Time StartDate, Date_Time FromDate, Date_Time ToDate) { List<Date_Time> DateTimes = new List<Date_Time>(); DateTimes.AddRange(StaticOccurrences); // If the Recur is restricted by COUNT, we need to evaluate just // after any static occurrences so it's correctly restricted to a // certain number. NOTE: fixes bug #13 and bug #16 if (Count > 0) { FromDate = StartDate; foreach (Date_Time dt in StaticOccurrences) { if (FromDate < dt) FromDate = dt.AddSeconds(1); } } // Handle "UNTIL" values that are date-only. If we didn't change values here, "UNTIL" would // exclude the day it specifies, instead of the inclusive behaviour it should exhibit. if (Until != null && !Until.HasTime) Until.Value = new DateTime(Until.Year, Until.Month, Until.Day, 23, 59, 59, Until.Value.Kind); // Ignore recurrences that occur outside our time frame we're looking at if ((Until != null && FromDate > Until) || ToDate < StartDate) return DateTimes; // Narrow down our time range further to avoid over-processing if (Until != null && Until < ToDate) ToDate = Until; if (StartDate > FromDate) FromDate = StartDate; // If the frequency is WEEKLY, and the interval is greater than 1, // then we need to ensure that the StartDate occurs in one of the // "active" weeks, to ensure that we properly "step" through weeks. // NOTE: Fixes bug #1741093 - WEEKLY frequency eval behaves strangely if (Frequency == FrequencyType.WEEKLY && Interval > 1) { // Get the week of year of the time frame we want to calculate int firstEvalWeek = m_Calendar.GetWeekOfYear(FromDate.Value, System.Globalization.CalendarWeekRule.FirstFourDayWeek, Wkst); // Count backwards in years, calculating how many weeks' difference we have between // start date and evaluation period. Date_Time evalDate = FromDate; while (evalDate.Year > StartDate.Year) { firstEvalWeek += m_Calendar.GetWeekOfYear(new DateTime(evalDate.Year - 1, 12, 31), System.Globalization.CalendarWeekRule.FirstFourDayWeek, Wkst); evalDate = evalDate.AddYears(-1); } // Determine the difference, in weeks, between the start date and the evaluation period. int startWeek = m_Calendar.GetWeekOfYear(StartDate.Value, System.Globalization.CalendarWeekRule.FirstFourDayWeek, Wkst); int weeksDifference = firstEvalWeek - startWeek; // Determine how many weeks the evaluation period needs to change // in order to "align" to the start date week, given the specified interval. int offset = 0; while (weeksDifference % Interval != 0) { weeksDifference--; offset++; } // Offset the week back to a "compatible" week for evaluation FromDate = FromDate.AddDays(-offset * 7); } // Create a temporary recurrence for populating // missing information using the 'StartDate'. Recur r = new Recur(); r.CopyFrom(this); // If an INTERVAL was not specified, default to 1 r.EnsureInterval(); // Fill in missing, necessary ByXXX values r.EnsureByXXXValues(StartDate); // Get the occurrences foreach (Date_Time occurrence in r.GetOccurrences(FromDate.Copy(), ToDate, r.Count)) { // NOTE: // Used to be DateTime.AddRange(r.GetOccurrences(FromDate.Copy(), ToDate, r.Count)) // By doing it this way, fixes bug #19. if (!DateTimes.Contains(occurrence)) DateTimes.Add(occurrence); } // Limit the count of returned recurrences if (Count != int.MinValue && DateTimes.Count > Count) DateTimes.RemoveRange(Count, DateTimes.Count - Count); // Process the UNTIL, and make sure the DateTimes // occur between FromDate and ToDate for (int i = DateTimes.Count - 1; i >= 0; i--) { Date_Time dt = (Date_Time)DateTimes[i]; if (dt > ToDate || dt < FromDate) DateTimes.RemoveAt(i); } // Assign missing values foreach (Date_Time dt in DateTimes) dt.MergeWith(StartDate); // Ensure that DateTimes have an assigned time if they occur less than dailyB foreach (Date_Time dt in DateTimes) { if (Frequency < FrequencyType.DAILY) dt.HasTime = true; } return DateTimes; }
public void TEST1() { iCalendar iCal = new iCalendar(); Event evt = iCal.Create<Event>(); evt.Summary = "Event summary"; evt.Start = DateTime.SpecifyKind(DateTime.Today, DateTimeKind.Utc); Recur recur = new Recur(); evt.AddRecurrence(recur); try { List<Period> periods = evt.Evaluate(DateTime.Today.AddDays(1), DateTime.Today.AddDays(2)); Assert.Fail("An exception should be thrown when evaluating a recurrence with no specified FREQUENCY"); } catch { } }
private void DetermineStartingRecurrence(Recur recur, ref Date_Time dt) { if (recur.Count != int.MinValue) dt = DTStart.Copy(); else recur.IncrementDate(dt, -recur.Interval); }
public TimeCalculation(Date_Time StartDate, Date_Time EndDate, Recur Recur) { this.StartDate = StartDate; this.EndDate = EndDate; this.Recur = Recur; Year = StartDate.Value.Year; Month = StartDate.Value.Month; Day = StartDate.Value.Day; Hour = StartDate.Value.Hour; Minute = StartDate.Value.Minute; Second = StartDate.Value.Second; YearDays = new ArrayList(Recur.ByYearDay); ByDays = new ArrayList(Recur.ByDay); Months = new ArrayList(Recur.ByMonth); Days = new ArrayList(Recur.ByMonthDay); Hours = new ArrayList(Recur.ByHour); Minutes = new ArrayList(Recur.ByMinute); Seconds = new ArrayList(Recur.BySecond); DateTimes = new ArrayList(); // Only check what months and days are possible for // the week's period of time we're evaluating // NOTE: fixes RRULE10 evaluation if (Recur.Frequency == FrequencyType.WEEKLY) { if (Months.Count == 0) { Months.Add(StartDate.Value.Month); if (StartDate.Value.Month != EndDate.Value.Month) Months.Add(EndDate.Value.Month); } if (Days.Count == 0) { DateTime dt = StartDate.Value; while (dt < EndDate.Value) { Days.Add(dt.Day); dt = dt.AddDays(1); } Days.Add(EndDate.Value.Day); } } else { if (Months.Count == 0) Months.AddRange(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }); if (Days.Count == 0) Days.AddRange(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }); } }
public DaySpecifierSerializer(Recur.DaySpecifier byday) : base(byday) { this.m_DaySpecifier = byday; }
public override bool TryParse(string value, ref object obj) { Recur r = (Recur)obj; Match match = Regex.Match(value, @"FREQ=(SECONDLY|MINUTELY|HOURLY|DAILY|WEEKLY|MONTHLY|YEARLY);?(.*)", RegexOptions.IgnoreCase); if (match.Success) { // Parse the frequency type r.Frequency = (FrequencyType)Enum.Parse(typeof(FrequencyType), match.Groups[1].Value); // NOTE: fixed a bug where the group 2 match // resulted in an empty string, which caused // an error. if (match.Groups[2].Success && match.Groups[2].Length > 0) { string[] keywordPairs = match.Groups[2].Value.Split(';'); foreach (string keywordPair in keywordPairs) { string[] keyValues = keywordPair.Split('='); string keyword = keyValues[0]; string keyValue = keyValues[1]; switch (keyword.ToUpper()) { case "UNTIL": r.Until = new Date_Time(keyValue); break; case "COUNT": r.Count = Convert.ToInt32(keyValue); break; case "INTERVAL": r.Interval = Convert.ToInt32(keyValue); break; case "BYSECOND": AddInt32Values(r.BySecond, keyValue); break; case "BYMINUTE": AddInt32Values(r.ByMinute, keyValue); break; case "BYHOUR": AddInt32Values(r.ByHour, keyValue); break; case "BYDAY": { string[] days = keyValue.Split(','); foreach (string day in days) { r.ByDay.Add(new DaySpecifier(day)); } } break; case "BYMONTHDAY": AddInt32Values(r.ByMonthDay, keyValue); break; case "BYYEARDAY": AddInt32Values(r.ByYearDay, keyValue); break; case "BYWEEKNO": AddInt32Values(r.ByWeekNo, keyValue); break; case "BYMONTH": AddInt32Values(r.ByMonth, keyValue); break; case "BYSETPOS": AddInt32Values(r.BySetPos, keyValue); break; case "WKST": r.Wkst = GetDayOfWeek(keyValue); break; } } } } else if ((match = Regex.Match(value, @"every\s+(?<Interval>other|\d+)?\w{0,2}\s*(?<Freq>second|minute|hour|day|week|month|year)s?,?\s*(?<More>.+)", RegexOptions.IgnoreCase)).Success) { if (match.Groups["Interval"].Success) { int interval; if (!int.TryParse(match.Groups["Interval"].Value, out interval)) { r.Interval = 2; // "other" } else { r.Interval = interval; } } else { r.Interval = 1; } switch (match.Groups["Freq"].Value.ToLower()) { case "second": r.Frequency = FrequencyType.SECONDLY; break; case "minute": r.Frequency = FrequencyType.MINUTELY; break; case "hour": r.Frequency = FrequencyType.HOURLY; break; case "day": r.Frequency = FrequencyType.DAILY; break; case "week": r.Frequency = FrequencyType.WEEKLY; break; case "month": r.Frequency = FrequencyType.MONTHLY; break; case "year": r.Frequency = FrequencyType.YEARLY; break; } string[] values = match.Groups["More"].Value.Split(','); foreach (string item in values) { if ((match = Regex.Match(item, @"(?<Num>\d+)\w\w\s+(?<Type>second|minute|hour|day|week|month)", RegexOptions.IgnoreCase)).Success || (match = Regex.Match(item, @"(?<Type>second|minute|hour|day|week|month)\s+(?<Num>\d+)", RegexOptions.IgnoreCase)).Success) { int num; if (int.TryParse(match.Groups["Num"].Value, out num)) { switch (match.Groups["Type"].Value.ToLower()) { case "second": r.BySecond.Add(num); break; case "minute": r.ByMinute.Add(num); break; case "hour": r.ByHour.Add(num); break; case "day": switch (r.Frequency) { case FrequencyType.YEARLY: r.ByYearDay.Add(num); break; case FrequencyType.MONTHLY: r.ByMonthDay.Add(num); break; } break; case "week": r.ByWeekNo.Add(num); break; case "month": r.ByMonth.Add(num); break; } } } else if ((match = Regex.Match(item, @"(?<Num>\d+\w{0,2})?(\w|\s)+?(?<First>first)?(?<Last>last)?\s*((?<Day>sunday|monday|tuesday|wednesday|thursday|friday|saturday)\s*(and|or)?\s*)+", RegexOptions.IgnoreCase)).Success) { int num = int.MinValue; if (match.Groups["Num"].Success) { if (int.TryParse(match.Groups["Num"].Value, out num)) { if (match.Groups["Last"].Success) { // Make number negative num *= -1; } } } else if (match.Groups["Last"].Success) { num = -1; } else if (match.Groups["First"].Success) { num = 1; } foreach (Capture capture in match.Groups["Day"].Captures) { DaySpecifier ds = new DaySpecifier((DayOfWeek)Enum.Parse(typeof(DayOfWeek), capture.Value, true)); ds.Num = num; r.ByDay.Add(ds); } } else if ((match = Regex.Match(item, @"at\s+(?<Hour>\d{1,2})(:(?<Minute>\d{2})((:|\.)(?<Second>\d{2}))?)?\s*(?<Meridian>(a|p)m?)?", RegexOptions.IgnoreCase)).Success) { int hour, minute, second; if (int.TryParse(match.Groups["Hour"].Value, out hour)) { // Adjust for PM if (match.Groups["Meridian"].Success && match.Groups["Meridian"].Value.ToUpper().StartsWith("P")) { hour += 12; } r.ByHour.Add(hour); if (match.Groups["Minute"].Success && int.TryParse(match.Groups["Minute"].Value, out minute)) { r.ByMinute.Add(minute); if (match.Groups["Second"].Success && int.TryParse(match.Groups["Second"].Value, out second)) { r.BySecond.Add(second); } } } } else if ((match = Regex.Match(item, @"^\s*until\s+(?<DateTime>.+)$", RegexOptions.IgnoreCase)).Success) { DateTime dt = DateTime.Parse(match.Groups["DateTime"].Value); DateTime.SpecifyKind(dt, DateTimeKind.Utc); r.Until = new Date_Time(dt); } else if ((match = Regex.Match(item, @"^\s*for\s+(?<Count>\d+)\s+occurrences\s*$", RegexOptions.IgnoreCase)).Success) { int count; if (!int.TryParse(match.Groups["Count"].Value, out count)) { return(false); } else { r.Count = count; } } } } else { return(false); } CheckMutuallyExclusive("COUNT", "UNTIL", r.Count, r.Until); CheckRange("INTERVAL", r.Interval, 1, int.MaxValue); CheckRange("COUNT", r.Count, 1, int.MaxValue); CheckRange("BYSECOND", r.BySecond, 0, 59); CheckRange("BYMINUTE", r.ByMinute, 0, 59); CheckRange("BYHOUR", r.ByHour, 0, 23); CheckRange("BYMONTHDAY", r.ByMonthDay, -31, 31); CheckRange("BYYEARDAY", r.ByYearDay, -366, 366); CheckRange("BYWEEKNO", r.ByWeekNo, -53, 53); CheckRange("BYMONTH", r.ByMonth, 1, 12); CheckRange("BYSETPOS", r.BySetPos, -366, 366); return(true); }
public override bool TryParse(string value, ref object obj) { Recur r = (Recur)obj; Match match = Regex.Match(value, @"(SECONDLY|MINUTELY|HOURLY|DAILY|WEEKLY|MONTHLY|YEARLY);?(.*)", RegexOptions.IgnoreCase); if (match.Success) { // Parse the frequency type r.Frequency = (FrequencyType)Enum.Parse(typeof(FrequencyType), match.Groups[1].Value); if (match.Groups[2].Success) { string[] keywordPairs = match.Groups[2].Value.Split(';'); foreach (string keywordPair in keywordPairs) { string[] keyValues = keywordPair.Split('='); string keyword = keyValues[0]; string keyValue = keyValues[1]; switch (keyword.ToUpper()) { case "UNTIL": r.Until = new Date_Time(keyValue); break; case "COUNT": r.Count = Convert.ToInt32(keyValue); break; case "INTERVAL": r.Interval = Convert.ToInt32(keyValue); break; case "BYSECOND": AddInt32Values(r.BySecond, keyValue); break; case "BYMINUTE": AddInt32Values(r.ByMinute, keyValue); break; case "BYHOUR": AddInt32Values(r.ByHour, keyValue); break; case "BYDAY": { string[] days = keyValue.Split(','); foreach (string day in days) { r.ByDay.Add(new ByDay(day)); } } break; case "BYMONTHDAY": AddInt32Values(r.ByMonthDay, keyValue); break; case "BYYEARDAY": AddInt32Values(r.ByYearDay, keyValue); break; case "BYWEEKNO": AddInt32Values(r.ByWeekNo, keyValue); break; case "BYMONTH": AddInt32Values(r.ByMonth, keyValue); break; case "BYSETPOS": AddInt32Values(r.BySetPos, keyValue); break; case "WKST": r.Wkst = GetDayOfWeek(keyValue); break; } } } CheckMutuallyExclusive("COUNT", "UNTIL", r.Count, r.Until); CheckRange("INTERVAL", r.Interval, 1, int.MaxValue); CheckRange("COUNT", r.Count, 1, int.MaxValue); CheckRange("BYSECOND", r.BySecond, 0, 59); CheckRange("BYMINUTE", r.ByMinute, 0, 59); CheckRange("BYHOUR", r.ByHour, 0, 23); CheckRange("BYMONTHDAY", r.ByMonthDay, -31, 31); CheckRange("BYYEARDAY", r.ByYearDay, -366, 366); CheckRange("BYWEEKNO", r.ByWeekNo, -53, 53); CheckRange("BYMONTH", r.ByMonth, 1, 12); CheckRange("BYSETPOS", r.BySetPos, -366, 366); return(true); } return(false); }
public ArrayList Evaluate(Date_Time StartDate, Date_Time FromDate, Date_Time ToDate) { ArrayList DateTimes = new ArrayList(); // Handle "UNTIL" values that are date-only. Without changing values here, "UNTIL" will // exclude the day it specifies, instead of the inclusive behaviour it should exhibit. if (Until != null && !Until.HasTime) { Until = new Date_Time(new DateTime(Until.Value.Year, Until.Value.Month, Until.Value.Day, 23, 59, 59, Until.Value.Kind)); } // Ignore recurrences that occur outside our time frame we're looking at if ((Until != null && FromDate > Until) || ToDate < StartDate) { return(DateTimes); } // Narrow down our time range further to avoid over-processing if (Until != null && Until < ToDate) { ToDate = Until; } if (StartDate > FromDate) { FromDate = StartDate; } // Create a temporary recurrence for populating // missing information using the 'StartDate'. Recur r = new Recur(); r.CopyFrom(this); // If an INTERVAL was not specified, default to 1 r.EnsureInterval(); // Fill in missing, necessary ByXXX values r.EnsureByXXXValues(StartDate); // Get the occurrences DateTimes = r.GetOccurrences(new Date_Time(FromDate), ToDate, r.Count); // Limit the count of returned recurrences if (Count != int.MinValue && DateTimes.Count > Count) { DateTimes.RemoveRange(Count, DateTimes.Count - Count); } // Process the UNTIL, and make sure the DateTimes // occur between FromDate and ToDate for (int i = DateTimes.Count - 1; i >= 0; i--) { DateTime dt = (DateTime)DateTimes[i]; if (dt > ToDate.Value || dt < FromDate.Value) { DateTimes.RemoveAt(i); } } return(DateTimes); }
public List <Date_Time> Evaluate(Date_Time StartDate, Date_Time FromDate, Date_Time ToDate) { List <Date_Time> DateTimes = new List <Date_Time>(); // If the Recur is restricted by COUNT, we need to evaluate from the first occurrence // so it's correctly restricted to a certain number. // NOTE: fixes bug #13 if (Count > 0) { FromDate = StartDate; } // Handle "UNTIL" values that are date-only. Without changing values here, "UNTIL" will // exclude the day it specifies, instead of the inclusive behaviour it should exhibit. if (Until != null && !Until.HasTime) { Until.Value = new DateTime(Until.Year, Until.Month, Until.Day, 23, 59, 59, Until.Value.Kind); } // Ignore recurrences that occur outside our time frame we're looking at if ((Until != null && FromDate > Until) || ToDate < StartDate) { return(DateTimes); } // Narrow down our time range further to avoid over-processing if (Until != null && Until < ToDate) { ToDate = Until; } if (StartDate > FromDate) { FromDate = StartDate; } // Create a temporary recurrence for populating // missing information using the 'StartDate'. Recur r = new Recur(); r.CopyFrom(this); // If an INTERVAL was not specified, default to 1 r.EnsureInterval(); // Fill in missing, necessary ByXXX values r.EnsureByXXXValues(StartDate); // Get the occurrences DateTimes = r.GetOccurrences(FromDate.Copy(), ToDate, r.Count); // Limit the count of returned recurrences if (Count != int.MinValue && DateTimes.Count > Count) { DateTimes.RemoveRange(Count, DateTimes.Count - Count); } // Process the UNTIL, and make sure the DateTimes // occur between FromDate and ToDate for (int i = DateTimes.Count - 1; i >= 0; i--) { Date_Time dt = (Date_Time)DateTimes[i]; if (dt > ToDate || dt < FromDate) { DateTimes.RemoveAt(i); } } // Assign missing values foreach (Date_Time dt in DateTimes) { dt.MergeWith(StartDate); } return(DateTimes); }
public void SERIALIZE18() { iCalendar iCal = new iCalendar(); Event evt = iCal.Create<Event>(); evt.Summary = "Test event title"; evt.Start = DateTime.Today; evt.End = DateTime.Today.AddDays(1); evt.IsAllDay = true; Recur rec = new Recur("FREQ=WEEKLY;INTERVAL=3;BYDAY=TU,FR,SU;COUNT=4"); evt.AddRecurrence(rec); iCalendarSerializer serializer = new iCalendarSerializer(iCal); string icalString = serializer.SerializeToString(); Assert.IsNotEmpty(icalString, "iCalendarSerializer.SerializeToString() must not be empty"); ComponentBaseSerializer compSerializer = new ComponentBaseSerializer(evt); string evtString = compSerializer.SerializeToString(); Assert.IsTrue(evtString.Equals("BEGIN:VEVENT\r\nDTEND:20070320T060000Z\r\nDTSTART;VALUE=DATE:20070319\r\nDURATION:P1D\r\nRRULE:FREQ=WEEKLY;INTERVAL=3;COUNT=4;BYDAY=TU,FR,SU\r\nSUMMARY:Test event title\r\nEND:VEVENT\r\n"), "ComponentBaseSerializer.SerializeToString() serialized incorrectly"); }
public void SERIALIZE19() { iCalendar iCal = new iCalendar(); Event evt = iCal.Create<Event>(); evt.Summary = "Test event title"; evt.Start = new Date_Time(2007, 4, 29); evt.End = evt.Start.AddDays(1); evt.IsAllDay = true; Recur rec = new Recur("FREQ=WEEKLY;INTERVAL=3;BYDAY=TU,FR,SU;COUNT=4"); evt.AddRecurrence(rec); ComponentBaseSerializer compSerializer = new ComponentBaseSerializer(evt); FileStream fs = new FileStream(@"Calendars\Serialization\SERIALIZE19.ics", FileMode.Create, FileAccess.Write); compSerializer.Serialize(fs, Encoding.UTF8); fs.Close(); iCalendar iCal1 = new iCalendar(); fs = new FileStream(@"Calendars\Serialization\SERIALIZE19.ics", FileMode.Open, FileAccess.Read); Event evt1 = ComponentBase.LoadFromStream<Event>(fs); fs.Close(); CompareComponents(evt, evt1); }
public List <Date_Time> Evaluate(Date_Time StartDate, Date_Time FromDate, Date_Time ToDate) { List <Date_Time> DateTimes = new List <Date_Time>(); DateTimes.AddRange(StaticOccurrences); // If the Recur is restricted by COUNT, we need to evaluate just // after any static occurrences so it's correctly restricted to a // certain number. NOTE: fixes bug #13 and bug #16 if (Count > 0) { FromDate = StartDate; foreach (Date_Time dt in StaticOccurrences) { if (FromDate < dt) { FromDate = dt.AddSeconds(1); } } } // Handle "UNTIL" values that are date-only. If we didn't change values here, "UNTIL" would // exclude the day it specifies, instead of the inclusive behaviour it should exhibit. if (Until != null && !Until.HasTime) { Until.Value = new DateTime(Until.Year, Until.Month, Until.Day, 23, 59, 59, Until.Value.Kind); } // Ignore recurrences that occur outside our time frame we're looking at if ((Until != null && FromDate > Until) || ToDate < StartDate) { return(DateTimes); } // Narrow down our time range further to avoid over-processing if (Until != null && Until < ToDate) { ToDate = Until; } if (StartDate > FromDate) { FromDate = StartDate; } // If the frequency is WEEKLY, and the interval is greater than 1, // then we need to ensure that the StartDate occurs in one of the // "active" weeks, to ensure that we properly "step" through weeks. // NOTE: Fixes bug #1741093 - WEEKLY frequency eval behaves strangely if (Frequency == FrequencyType.WEEKLY && Interval > 1) { // Get the week of year of the time frame we want to calculate int firstEvalWeek = m_Calendar.GetWeekOfYear(FromDate.Value, System.Globalization.CalendarWeekRule.FirstFourDayWeek, Wkst); // Count backwards in years, calculating how many weeks' difference we have between // start date and evaluation period. Date_Time evalDate = FromDate; while (evalDate.Year > StartDate.Year) { firstEvalWeek += m_Calendar.GetWeekOfYear(new DateTime(evalDate.Year - 1, 12, 31), System.Globalization.CalendarWeekRule.FirstFourDayWeek, Wkst); evalDate = evalDate.AddYears(-1); } // Determine the difference, in weeks, between the start date and the evaluation period. int startWeek = m_Calendar.GetWeekOfYear(StartDate.Value, System.Globalization.CalendarWeekRule.FirstFourDayWeek, Wkst); int weeksDifference = firstEvalWeek - startWeek; // Determine how many weeks the evaluation period needs to change // in order to "align" to the start date week, given the specified interval. int offset = 0; while (weeksDifference % Interval != 0) { weeksDifference--; offset++; } // Offset the week back to a "compatible" week for evaluation FromDate = FromDate.AddDays(-offset * 7); } // Create a temporary recurrence for populating // missing information using the 'StartDate'. Recur r = new Recur(); r.CopyFrom(this); // If an INTERVAL was not specified, default to 1 r.EnsureInterval(); // Fill in missing, necessary ByXXX values r.EnsureByXXXValues(StartDate); // Get the occurrences foreach (Date_Time occurrence in r.GetOccurrences(FromDate.Copy(), ToDate, r.Count)) { // NOTE: // Used to be DateTime.AddRange(r.GetOccurrences(FromDate.Copy(), ToDate, r.Count)) // By doing it this way, fixes bug #19. if (!DateTimes.Contains(occurrence)) { DateTimes.Add(occurrence); } } // Limit the count of returned recurrences if (Count != int.MinValue && DateTimes.Count > Count) { DateTimes.RemoveRange(Count, DateTimes.Count - Count); } // Process the UNTIL, and make sure the DateTimes // occur between FromDate and ToDate for (int i = DateTimes.Count - 1; i >= 0; i--) { Date_Time dt = (Date_Time)DateTimes[i]; if (dt > ToDate || dt < FromDate) { DateTimes.RemoveAt(i); } } // Assign missing values foreach (Date_Time dt in DateTimes) { dt.MergeWith(StartDate); } // Ensure that DateTimes have an assigned time if they occur less than dailyB foreach (Date_Time dt in DateTimes) { if (Frequency < FrequencyType.DAILY) { dt.HasTime = true; } } return(DateTimes); }
public List<Date_Time> Evaluate(Date_Time StartDate, Date_Time FromDate, Date_Time ToDate) { List<Date_Time> DateTimes = new List<Date_Time>(); DateTimes.AddRange(StaticOccurrences); // If the Recur is restricted by COUNT, we need to evaluate just // after any static occurrences so it's correctly restricted to a // certain number. NOTE: fixes bug #13 and bug #16 if (Count > 0) { FromDate = StartDate; foreach (Date_Time dt in StaticOccurrences) { if (FromDate < dt) FromDate = dt.AddSeconds(1); } } // Handle "UNTIL" values that are date-only. If we didn't change values here, "UNTIL" would // exclude the day it specifies, instead of the inclusive behaviour it should exhibit. if (Until != null && !Until.HasTime) Until.Value = new DateTime(Until.Year, Until.Month, Until.Day, 23, 59, 59, Until.Value.Kind); // Ignore recurrences that occur outside our time frame we're looking at if ((Until != null && FromDate > Until) || ToDate < StartDate) return DateTimes; // Narrow down our time range further to avoid over-processing if (Until != null && Until < ToDate) ToDate = Until; if (StartDate > FromDate) FromDate = StartDate; // Create a temporary recurrence for populating // missing information using the 'StartDate'. Recur r = new Recur(); r.CopyFrom(this); // If an INTERVAL was not specified, default to 1 r.EnsureInterval(); // Fill in missing, necessary ByXXX values r.EnsureByXXXValues(StartDate); // Get the occurrences foreach (Date_Time occurrence in r.GetOccurrences(FromDate.Copy(), ToDate, r.Count)) { // NOTE: // Used to be DateTime.AddRange(r.GetOccurrences(FromDate.Copy(), ToDate, r.Count)) // By doing it this way, fixes bug #19. if (!DateTimes.Contains(occurrence)) DateTimes.Add(occurrence); } // Limit the count of returned recurrences if (Count != int.MinValue && DateTimes.Count > Count) DateTimes.RemoveRange(Count, DateTimes.Count - Count); // Process the UNTIL, and make sure the DateTimes // occur between FromDate and ToDate for (int i = DateTimes.Count - 1; i >= 0; i--) { Date_Time dt = (Date_Time)DateTimes[i]; if (dt > ToDate || dt < FromDate) DateTimes.RemoveAt(i); } // Assign missing values foreach (Date_Time dt in DateTimes) dt.MergeWith(StartDate); // Ensure that DateTimes have an assigned time if they occur less than dailyB foreach (Date_Time dt in DateTimes) { if (Frequency < FrequencyType.DAILY) dt.HasTime = true; } return DateTimes; }
public List <Date_Time> Evaluate(Date_Time StartDate, Date_Time FromDate, Date_Time ToDate) { List <Date_Time> DateTimes = new List <Date_Time>(); DateTimes.AddRange(StaticOccurrences); // If the Recur is restricted by COUNT, we need to evaluate just // after any static occurrences so it's correctly restricted to a // certain number. NOTE: fixes bug #13 and bug #16 if (Count > 0) { FromDate = StartDate; foreach (Date_Time dt in StaticOccurrences) { if (FromDate < dt) { FromDate = dt.AddSeconds(1); } } } // Handle "UNTIL" values that are date-only. If we didn't change values here, "UNTIL" would // exclude the day it specifies, instead of the inclusive behaviour it should exhibit. if (Until != null && !Until.HasTime) { Until.Value = new DateTime(Until.Year, Until.Month, Until.Day, 23, 59, 59, Until.Value.Kind); } // Ignore recurrences that occur outside our time frame we're looking at if ((Until != null && FromDate > Until) || ToDate < StartDate) { return(DateTimes); } // Narrow down our time range further to avoid over-processing if (Until != null && Until < ToDate) { ToDate = Until; } if (StartDate > FromDate) { FromDate = StartDate; } // Create a temporary recurrence for populating // missing information using the 'StartDate'. Recur r = new Recur(); r.CopyFrom(this); // If an INTERVAL was not specified, default to 1 r.EnsureInterval(); // Fill in missing, necessary ByXXX values r.EnsureByXXXValues(StartDate); // Get the occurrences foreach (Date_Time occurrence in r.GetOccurrences(FromDate.Copy(), ToDate, r.Count)) { // NOTE: // Used to be DateTime.AddRange(r.GetOccurrences(FromDate.Copy(), ToDate, r.Count)) // By doing it this way, fixes bug #19. if (!DateTimes.Contains(occurrence)) { DateTimes.Add(occurrence); } } // Limit the count of returned recurrences if (Count != int.MinValue && DateTimes.Count > Count) { DateTimes.RemoveRange(Count, DateTimes.Count - Count); } // Process the UNTIL, and make sure the DateTimes // occur between FromDate and ToDate for (int i = DateTimes.Count - 1; i >= 0; i--) { Date_Time dt = (Date_Time)DateTimes[i]; if (dt > ToDate || dt < FromDate) { DateTimes.RemoveAt(i); } } // Assign missing values foreach (Date_Time dt in DateTimes) { dt.MergeWith(StartDate); } // Ensure that DateTimes have an assigned time if they occur less than dailyB foreach (Date_Time dt in DateTimes) { if (Frequency < FrequencyType.DAILY) { dt.HasTime = true; } } return(DateTimes); }
//[Test, Category("Serialization")] public void XCAL1() { iCalendar iCal = new iCalendar(); Event evt = iCal.Create<Event>(); evt.Summary = "Test event title"; evt.Start = new Date_Time(2007, 4, 29); evt.End = evt.Start.AddDays(1); evt.IsAllDay = true; Recur rec = new Recur("FREQ=WEEKLY;INTERVAL=3;BYDAY=TU,FR,SU;COUNT=4"); evt.AddRecurrence(rec); xCalSerializer serializer = new xCalSerializer(iCal); serializer.Serialize(@"Calendars\Serialization\XCAL1.xcal"); SerializeTest("XCAL1.xcal", typeof(xCalSerializer)); }
public void SERIALIZE18() { iCalendar iCal = new iCalendar(); Event evt = iCal.Create<Event>(); evt.Summary = "Test event title"; evt.Start = new Date_Time(2007, 3, 19); evt.Start.Kind = DateTimeKind.Utc; evt.Duration = new TimeSpan(24, 0, 0); evt.Created = evt.Start.Copy(); evt.DTStamp = evt.Start.Copy(); evt.UID = "123456789"; evt.IsAllDay = true; Recur rec = new Recur("FREQ=WEEKLY;INTERVAL=3;BYDAY=TU,FR,SU;COUNT=4"); evt.AddRecurrence(rec); iCalendarSerializer serializer = new iCalendarSerializer(iCal); string icalString = serializer.SerializeToString(); Assert.IsNotEmpty(icalString, "iCalendarSerializer.SerializeToString() must not be empty"); ComponentBaseSerializer compSerializer = new ComponentBaseSerializer(evt); string evtString = compSerializer.SerializeToString(); Assert.IsTrue(evtString.Equals("BEGIN:VEVENT\r\nCREATED:20070319T000000Z\r\nDTEND:20070320T000000Z\r\nDTSTAMP:20070319T000000Z\r\nDTSTART;VALUE=DATE:20070319\r\nDURATION:P1D\r\nRRULE:FREQ=WEEKLY;INTERVAL=3;COUNT=4;BYDAY=TU,FR,SU\r\nSUMMARY:Test event title\r\nUID:123456789\r\nEND:VEVENT\r\n"), "ComponentBaseSerializer.SerializeToString() serialized incorrectly"); }
// FIXME: add similar methods for RDATE and EXDATE /// <summary> /// Adds a recurrence rule to the recurring component /// </summary> /// <param name="recur">The recurrence rule to add</param> public void AddRecurrence(Recur recur) { if (RRule != null) { Recur[] rules = new Recur[RRule.Length + 1]; RRule.CopyTo(rules, 0); rules[rules.Length - 1] = recur; RRule = rules; } else RRule = new Recur[] { recur }; }
public ArrayList Evaluate(Date_Time StartDate, Date_Time FromDate, Date_Time ToDate) { ArrayList DateTimes = new ArrayList(); // Handle "UNTIL" values that are date-only. Without changing values here, "UNTIL" will // exclude the day it specifies, instead of the inclusive behaviour it should exhibit. if (Until != null && !Until.HasTime) Until.Value = new DateTime(Until.Year, Until.Month, Until.Day, 23, 59, 59, Until.Value.Kind); // Ignore recurrences that occur outside our time frame we're looking at if ((Until != null && FromDate > Until) || ToDate < StartDate) return DateTimes; // Narrow down our time range further to avoid over-processing if (Until != null && Until < ToDate) ToDate = Until; if (StartDate > FromDate) FromDate = StartDate; // Create a temporary recurrence for populating // missing information using the 'StartDate'. Recur r = new Recur(); r.CopyFrom(this); // If an INTERVAL was not specified, default to 1 r.EnsureInterval(); // Fill in missing, necessary ByXXX values r.EnsureByXXXValues(StartDate); // Get the occurrences DateTimes = r.GetOccurrences(FromDate.Copy(), ToDate, r.Count); // Limit the count of returned recurrences if (Count != int.MinValue && DateTimes.Count > Count) DateTimes.RemoveRange(Count, DateTimes.Count - Count); // Process the UNTIL, and make sure the DateTimes // occur between FromDate and ToDate for (int i = DateTimes.Count - 1; i >= 0; i--) { Date_Time dt = (Date_Time)DateTimes[i]; if (dt > ToDate || dt < FromDate) DateTimes.RemoveAt(i); } // Assign missing values foreach (Date_Time dt in DateTimes) dt.MergeWith(StartDate); return DateTimes; }
/// <summary> /// Adds an exception recurrence rule to the recurring component /// </summary> /// <param name="recur">The recurrence rule to add</param> public void AddException(Recur recur) { if (ExRule != null) { Recur[] rules = new Recur[ExRule.Length + 1]; ExRule.CopyTo(rules, 0); rules[rules.Length - 1] = recur; ExRule = rules; } else ExRule = new Recur[] { recur }; }
public bool CheckValidDate(Recur r, Date_Time Date) { bool valid = false; if (this.DayOfWeek == Date.Value.DayOfWeek) valid = true; if (valid && this.Num != int.MinValue) { int mult = (this.Num < 0) ? -1 : 1; int offset = (this.Num < 0) ? 1 : 0; int abs = Math.Abs(this.Num); switch (r.Frequency) { case Recur.FrequencyType.MONTHLY: { DateTime mondt = new DateTime(Date.Value.Year, Date.Value.Month, 1, Date.Value.Hour, Date.Value.Minute, Date.Value.Second, Date.Value.Kind); mondt = DateTime.SpecifyKind(mondt, Date.Value.Kind); if (offset > 0) mondt = mondt.AddMonths(1).AddDays(-1); while (mondt.DayOfWeek != this.DayOfWeek) mondt = mondt.AddDays(mult); for (int i = 1; i < abs; i++) mondt = mondt.AddDays(7 * mult); if (Date.Value.Date != mondt.Date) valid = false; } break; case Recur.FrequencyType.YEARLY: { // If BYMONTH is specified, then offset our tests // by those months; otherwise, begin with Jan. 1st. // NOTE: fixes USHolidays.ics eval ArrayList months = new ArrayList(); if (r.ByMonth.Count == 0) months.Add(1); else months = r.ByMonth; bool found = false; foreach (int month in months) { DateTime yeardt = new DateTime(Date.Value.Year, month, 1, Date.Value.Hour, Date.Value.Minute, Date.Value.Second, Date.Value.Kind); yeardt = DateTime.SpecifyKind(yeardt, Date.Value.Kind); if (offset > 0) { // Start at end of year, or end of month if BYMONTH is specified if (r.ByMonth.Count == 0) yeardt = yeardt.AddYears(1).AddDays(-1); else yeardt = yeardt.AddMonths(1).AddDays(-1); } while (yeardt.DayOfWeek != this.DayOfWeek) yeardt = yeardt.AddDays(mult); for (int i = 1; i < abs; i++) yeardt = yeardt.AddDays(7 * mult); if (Date.Value == yeardt) found = true; } if (!found) valid = false; } break; // Ignore other frequencies default: break; } } return valid; }
public void RRULE43() { iCalendar iCal = new iCalendar(); DDay.iCal.Components.TimeZone tz = iCal.Create<DDay.iCal.Components.TimeZone>(); tz.TZID = "US-Eastern"; tz.Last_Modified = new DateTime(1987, 1, 1, 0, 0, 0, DateTimeKind.Utc); DDay.iCal.Components.TimeZone.TimeZoneInfo standard = new DDay.iCal.Components.TimeZone.TimeZoneInfo(DDay.iCal.Components.TimeZone.STANDARD, tz); standard.Start = new DateTime(1967, 10, 29, 2, 0, 0, DateTimeKind.Utc); standard.AddRecurrence(new Recur("FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10")); standard.TZOffsetFrom = new UTC_Offset("-0400"); standard.TZOffsetTo = new UTC_Offset("-0500"); standard.TimeZoneName = "EST"; DDay.iCal.Components.TimeZone.TimeZoneInfo daylight = new DDay.iCal.Components.TimeZone.TimeZoneInfo(DDay.iCal.Components.TimeZone.DAYLIGHT, tz); daylight.Start = new DateTime(1987, 4, 5, 2, 0, 0, DateTimeKind.Utc); daylight.AddRecurrence(new Recur("FREQ=YEARLY;BYDAY=1SU;BYMONTH=4")); daylight.TZOffsetFrom = new UTC_Offset("-0500"); daylight.TZOffsetTo = new UTC_Offset("-0400"); daylight.TimeZoneName = "EDT"; Event evt = iCal.Create<Event>(); evt.Summary = "Test event"; evt.Start = new Date_Time(2007, 1, 24, 8, 0, 0, tzid, iCal); evt.Duration = TimeSpan.FromHours(1); evt.End = new Date_Time(2007, 1, 24, 9, 0, 0, tzid, iCal); Recur recur = new Recur("FREQ=MONTHLY;INTERVAL=2;BYDAY=4WE"); evt.AddRecurrence(recur); List<Occurrence> occurrences = evt.GetOccurrences( new DateTime(2007, 1, 24), new DateTime(2007, 12, 31)); Date_Time[] DateTimes = new Date_Time[] { new Date_Time(2007, 1, 24, 8, 0, 0, tzid, iCal), new Date_Time(2007, 3, 28, 8, 0, 0, tzid, iCal), new Date_Time(2007, 5, 23, 8, 0, 0, tzid, iCal), new Date_Time(2007, 7, 25, 8, 0, 0, tzid, iCal), new Date_Time(2007, 9, 26, 8, 0, 0, tzid, iCal), new Date_Time(2007, 11, 28, 8, 0, 0, tzid, iCal) }; for (int i = 0; i < DateTimes.Length; i++) Assert.AreEqual(DateTimes[i], occurrences[i].Period.StartTime, "Event should occur on " + DateTimes[i]); Assert.AreEqual( DateTimes.Length, occurrences.Count, "There should be exactly " + DateTimes.Length + " occurrences; there were " + occurrences.Count); }
public bool CheckValidDate(Recur r, Date_Time Date) { bool valid = false; if (this.DayOfWeek == Date.Value.DayOfWeek) { valid = true; } if (valid && this.Num != int.MinValue) { int mult = (this.Num < 0) ? -1 : 1; int offset = (this.Num < 0) ? 1 : 0; int abs = Math.Abs(this.Num); switch (r.Frequency) { case Recur.FrequencyType.MONTHLY: { DateTime mondt = new DateTime(Date.Value.Year, Date.Value.Month, 1, Date.Value.Hour, Date.Value.Minute, Date.Value.Second, Date.Value.Kind); mondt = DateTime.SpecifyKind(mondt, Date.Value.Kind); if (offset > 0) { mondt = mondt.AddMonths(1).AddDays(-1); } while (mondt.DayOfWeek != this.DayOfWeek) { mondt = mondt.AddDays(mult); } for (int i = 1; i < abs; i++) { mondt = mondt.AddDays(7 * mult); } if (Date.Value.Date != mondt.Date) { valid = false; } } break; case Recur.FrequencyType.YEARLY: { // If BYMONTH is specified, then offset our tests // by those months; otherwise, begin with Jan. 1st. // NOTE: fixes USHolidays.ics eval List <int> months = new List <int>(); if (r.ByMonth.Count == 0) { months.Add(1); } else { months = r.ByMonth; } bool found = false; foreach (int month in months) { DateTime yeardt = new DateTime(Date.Value.Year, month, 1, Date.Value.Hour, Date.Value.Minute, Date.Value.Second, Date.Value.Kind); yeardt = DateTime.SpecifyKind(yeardt, Date.Value.Kind); if (offset > 0) { // Start at end of year, or end of month if BYMONTH is specified if (r.ByMonth.Count == 0) { yeardt = yeardt.AddYears(1).AddDays(-1); } else { yeardt = yeardt.AddMonths(1).AddDays(-1); } } while (yeardt.DayOfWeek != this.DayOfWeek) { yeardt = yeardt.AddDays(mult); } for (int i = 1; i < abs; i++) { yeardt = yeardt.AddDays(7 * mult); } if (Date.Value == yeardt) { found = true; } } if (!found) { valid = false; } } break; // Ignore other frequencies default: break; } } return(valid); }
public void TEST2() { iCalendar iCal = new iCalendar(); Event evt = iCal.Create<Event>(); evt.Summary = "Event summary"; evt.Start = DateTime.SpecifyKind(DateTime.Today, DateTimeKind.Utc); Recur recur = new Recur(); recur.Frequency = Recur.FrequencyType.DAILY; recur.Count = 3; recur.ByDay.Add(new Recur.DaySpecifier(DayOfWeek.Monday)); recur.ByDay.Add(new Recur.DaySpecifier(DayOfWeek.Wednesday)); recur.ByDay.Add(new Recur.DaySpecifier(DayOfWeek.Friday)); evt.AddRecurrence(recur); DDay.iCal.Serialization.iCalendar.DataTypes.RecurSerializer serializer = new DDay.iCal.Serialization.iCalendar.DataTypes.RecurSerializer(recur); Assert.IsTrue(string.Compare(serializer.SerializeToString(), "FREQ=DAILY;COUNT=3;BYDAY=MO,WE,FR") == 0, "Serialized recurrence string is incorrect"); }
public List<Date_Time> Evaluate(Date_Time StartDate, Date_Time FromDate, Date_Time ToDate) { List<Date_Time> DateTimes = new List<Date_Time>(); DateTimes.AddRange(StaticOccurrences); // Create a temporary recurrence for populating // missing information using the 'StartDate'. Recur r = new Recur(); r.CopyFrom(this); // Enforce evaluation engine rules r.EnforceEvaluationRestrictions(); // Fill in missing, necessary ByXXX values r.EnsureByXXXValues(StartDate); // Get the occurrences foreach (Date_Time occurrence in r.GetOccurrences(StartDate, FromDate.Copy(), ToDate.Copy(), r.Count)) { // NOTE: // Used to be DateTimes.AddRange(r.GetOccurrences(FromDate.Copy(), ToDate, r.Count)) // By doing it this way, fixes bug #19. if (!DateTimes.Contains(occurrence)) DateTimes.Add(occurrence); } // Limit the count of returned recurrences if (Count != int.MinValue && DateTimes.Count > Count) DateTimes.RemoveRange(Count, DateTimes.Count - Count); // Process the UNTIL, and make sure the DateTimes // occur between FromDate and ToDate for (int i = DateTimes.Count - 1; i >= 0; i--) { Date_Time dt = (Date_Time)DateTimes[i]; if (dt > ToDate || dt < FromDate) DateTimes.RemoveAt(i); } // Assign missing values foreach (Date_Time dt in DateTimes) dt.MergeWith(StartDate); // Ensure that DateTimes have an assigned time if they occur less than daily foreach (Date_Time dt in DateTimes) { if (Frequency < FrequencyType.DAILY) dt.HasTime = true; } return DateTimes; }