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; } } // 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 = _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 += _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 = _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); }*/ // If the interval is greater than 1, then we need to ensure that the StartDate occurs in one of the // "active" days/weeks/months/years/etc. to ensure that we properly "step" through the interval. // NOTE: Fixes bug #1741093 - WEEKLY frequency eval behaves strangely if (Interval > 1) { // Determine the difference between our two dates, using our frequency as the UNIT. long difference = DateUtils.DateDiff(this.Frequency, StartDate, FromDate, Wkst); while (difference % Interval > 0) { FromDate = DateUtils.AddFrequency(this.Frequency, FromDate, -1); difference--; } } // 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(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); // 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; }