public override bool TryParse(string value, ref object obj) { string[] values = value.Split(','); foreach (string v in values) { object dt = new Date_Time(); object p = new Period(); // // Set the iCalendar for each Date_Time object here, // so that any time zones applied to these objects will be // handled correctly. // NOTE: fixes RRULE30 eval, where EXDATE references a // DATE-TIME without a time zone; therefore, the time zone // is implied from DTSTART, and would fail to do a proper // time zone lookup, because it wasn't assigned an iCalendar // object. // if (((Date_Time)dt).TryParse(v, ref dt)) { ((Date_Time)dt).iCalendar = iCalendar; ((Date_Time)dt).TZID = TZID; Items.Add(dt); } else if (((Period)p).TryParse(v, ref p)) { ((Period)p).StartTime.iCalendar = ((Period)p).EndTime.iCalendar = iCalendar; ((Period)p).StartTime.TZID = ((Period)p).EndTime.TZID = TZID; Items.Add(p); } else return false; } return true; }
public Period(Date_Time start, TimeSpan duration) : this() { StartTime = start; Duration = new Duration(duration); EndTime = start + duration; }
public Period(DateTime start, DateTime end) : this() { StartTime = new Date_Time(start); EndTime = new Date_Time(end); Duration = new Duration(start - end); }
public Period(Date_Time start, Date_Time end) : this() { StartTime = start; EndTime = end; Duration = new Duration(end.Value - start.Value); }
public void RRULE1() { iCalendar iCal = iCalendar.LoadFromFile(@"Calendars\Recurrence\RRULE1.ics"); Program.TestCal(iCal); Event evt = iCal.Events[0]; List<Occurrence> occurrences = evt.GetOccurrences( new Date_Time(2006, 1, 1, tzid, iCal), new Date_Time(2011, 1, 1, tzid, iCal)); Date_Time dt = new Date_Time(2006, 1, 1, 8, 30, 0, tzid, iCal); int i = 0; while (dt.Year < 2011) { if ((dt > evt.Start) && (dt.Year % 2 == 1) && // Every-other year from 2005 (dt.Month == 1) && (dt.DayOfWeek == DayOfWeek.Sunday)) { Date_Time dt1 = dt.AddHours(1); Assert.AreEqual(dt, occurrences[i].Period.StartTime, "Event should occur at " + dt); Assert.AreEqual(dt1, occurrences[i + 1].Period.StartTime, "Event should occur at " + dt); i += 2; } dt = dt.AddDays(1); } }
public void TestAlarm(string Calendar, List<Date_Time> Dates, Date_Time Start, Date_Time End) { iCalendar iCal = iCalendar.LoadFromFile(@"Calendars\Alarm\" + Calendar); Program.TestCal(iCal); Event evt = (Event)iCal.Events[0]; Start.iCalendar = iCal; Start.TZID = tzid; End.iCalendar = iCal; End.TZID = tzid; evt.Evaluate(Start, End); for (int i = 0; i < Dates.Count; i++) { Dates[i].TZID = tzid; Dates[i].iCalendar = iCal; } // Poll all alarms that occurred between Start and End List<DDay.iCal.Components.Alarm.AlarmOccurrence> alarms = evt.PollAlarms(); foreach (DDay.iCal.Components.Alarm.AlarmOccurrence alarm in alarms) Assert.IsTrue(Dates.Contains(alarm.DateTime), "Alarm triggers at " + alarm.DateTime + ", but it should not."); Assert.IsTrue(Dates.Count == alarms.Count, "There were " + alarms.Count + " alarm occurrences; there should have been " + Dates.Count + "."); }
public override ArrayList Evaluate(Date_Time FromDate, Date_Time ToDate) { // Add the event itself, before recurrence rules are evaluated if (DTStart != null) DateTimes.Add(DTStart); return base.Evaluate(FromDate, ToDate); }
public Date_TimeUTCSerializer(Date_Time dt) : base(dt) { // Make a copy of the Date_Time object, so we don't alter // the original DateTime = dt.Copy(); // Set the Date_Time object to UTC time DateTime.SetKind(DateTimeKind.Utc); }
public Period(Date_Time start, Date_Time end) : this() { StartTime = start.Copy(); if (end != null) { EndTime = end.Copy(); Duration = new Duration(end.Value - start.Value); } }
public Period(Date_Time start, TimeSpan duration) : this() { StartTime = start.Copy(); if (duration != TimeSpan.MinValue) { Duration = new Duration(duration); EndTime = start + duration; } }
public override void CopyFrom(object obj) { if (obj is Period) { Period p = (Period)obj; StartTime = p.StartTime; EndTime = p.EndTime; Duration = p.Duration; } }
public override System.Collections.Generic.List<Period> Evaluate(Date_Time FromDate, Date_Time ToDate) { if (Start != null) { Period p = new Period(Start); if (!Periods.Contains(p)) Periods.Add(p); return base.Evaluate(FromDate, ToDate); } return new System.Collections.Generic.List<Period>(); }
public Date_TimeUTCSerializer(Date_Time dt) : base(dt) { // Make a copy of the Date_Time object, so we don't alter // the original DateTime = dt.Copy(); // Set the Date_Time object to UTC time DateTime = DateTime.UTC; // Ensure time is serialized DateTime.HasTime = true; }
public Date_TimeUTCSerializer(Date_Time dt) : base(dt) { // Make a copy of the Date_Time object, so we don't alter // the original DateTime = dt.Copy(); // Set the Date_Time object to UTC time DateTime = DateTime.UTC; // FIXME: this is the old way we did it; remove when verified //DateTime.SetKind(DateTimeKind.Utc); }
/// <summary> /// Use this method to determine if a todo item has been completed. /// This takes into account recurrence items and the previous date /// of completion, if any. /// </summary> /// <param name="DateTime">The date and time to test.</param> /// <returns>True if the todo item has been completed</returns> public bool IsCompleted(Date_Time currDt) { if (Status == Status.COMPLETED) { foreach (Date_Time dt in DateTimes) { if (dt > Completed && // The item has recurred after it was completed currDt > dt) // and the current date is after the recurrence date. return false; } return true; } return false; }
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; } }
protected List <Date_Time> GetExtraOccurrences(Date_Time StartDate, Date_Time AbsEndDate) { List <Date_Time> DateTimes = new List <Date_Time>(); Date_Time EndDate = new Date_Time(StartDate); AbsEndDate = AbsEndDate.AddSeconds(-1); IncrementDate(EndDate, 1); EndDate = EndDate.AddSeconds(-1); if (EndDate > AbsEndDate) { EndDate = AbsEndDate; } return(CalculateChildOccurrences(StartDate, EndDate)); }
protected ArrayList GetExtraOccurrences(Date_Time StartDate, Date_Time AbsEndDate) { ArrayList DateTimes = new ArrayList(); Date_Time EndDate = new Date_Time(StartDate); AbsEndDate = new Date_Time(AbsEndDate.Value.AddSeconds(-1)); IncrementDate(EndDate, 1); EndDate = new Date_Time(EndDate.Value.AddSeconds(-1)); if (EndDate > AbsEndDate) { EndDate = AbsEndDate; } return(CalculateChildOccurrences(StartDate, EndDate)); }
protected void EnsureByXXXValues(Date_Time StartDate) { // If the frequency is weekly, and // no day of week is specified, use // the original date's day of week. // NOTE: fixes RRULE7 and RRULE8 handling if (Frequency == FrequencyType.WEEKLY && ByDay.Count == 0) { this.ByDay.Add(new DaySpecifier(StartDate.Value.DayOfWeek)); } if (Frequency > FrequencyType.SECONDLY && this.BySecond.Count == 0) { this.BySecond.Add(StartDate.Value.Second); } if (Frequency > FrequencyType.MINUTELY && this.ByMinute.Count == 0) { this.ByMinute.Add(StartDate.Value.Minute); } if (Frequency > FrequencyType.HOURLY && this.ByHour.Count == 0) { this.ByHour.Add(StartDate.Value.Hour); } // If neither BYDAY, BYMONTHDAY, or BYYEARDAY is specified, // default to the current day of month // NOTE: fixes RRULE23 handling, added BYYEARDAY exclusion // to fix RRULE25 handling if (Frequency > FrequencyType.WEEKLY && this.ByMonthDay.Count == 0 && this.ByYearDay.Count == 0 && this.ByDay.Count == 0) { this.ByMonthDay.Add(StartDate.Value.Day); } // If neither BYMONTH nor BYYEARDAY is specified, default to // the current month // NOTE: fixes RRULE25 handling if (Frequency > FrequencyType.MONTHLY && this.ByYearDay.Count == 0 && this.ByDay.Count == 0 && this.ByMonth.Count == 0) { this.ByMonth.Add(StartDate.Value.Month); } }
public ArrayList Evaluate(Date_Time StartDate, Date_Time FromDate, Date_Time EndDate) { ArrayList Periods = new ArrayList(); if (StartDate > FromDate) FromDate = StartDate; if (EndDate < FromDate || FromDate > EndDate) return Periods; foreach (object obj in Items) Periods.Add(obj); return Periods; }
public override bool TryParse(string value, ref object obj) { string[] values = value.Split(','); foreach (string v in values) { object dt = new Date_Time(); object p = new Period(); if (((Date_Time)dt).TryParse(v, ref dt)) Items.Add(dt); else if (((Period)p).TryParse(v, ref p)) Items.Add(p); else return false; } return true; }
/// <summary> /// Evaulates the RRule component, and adds each specified DateTime /// to the <see cref="Periods"/> collection. /// </summary> /// <param name="FromDate">The beginning date of the range to evaluate.</param> /// <param name="ToDate">The end date of the range to evaluate.</param> protected void EvaluateRRule(Date_Time FromDate, Date_Time ToDate) { // Handle RRULEs if (RRule != null) { foreach (Recur rrule in RRule) { ArrayList DateTimes = rrule.Evaluate(DTStart, FromDate, ToDate); foreach (Date_Time dt in DateTimes) { if (!this.DateTimes.Contains(dt.Value)) this.DateTimes.Add(dt.Value); } } } }
/// <summary> /// Use this method to determine if a todo item has been completed. /// This takes into account recurrence items and the previous date /// of completion, if any. /// </summary> /// <param name="DateTime">The date and time to test.</param> /// <returns>True if the todo item has been completed</returns> public bool IsCompleted(Date_Time currDt) { if (Status == TodoStatus.COMPLETED) { if (Completed == null) return true; foreach (Period p in Periods) { if (p.StartTime > Completed && // The item has recurred after it was completed currDt >= p.StartTime) // and the current date is after or on the recurrence date. return false; } return true; } return false; }
protected void IncrementDate(Date_Time dt, int Interval) { DateTime old = dt.Value; switch (Frequency) { case FrequencyType.SECONDLY: dt.Value = old.AddSeconds(Interval); break; case FrequencyType.MINUTELY: dt.Value = new DateTime(old.Year, old.Month, old.Day, old.Hour, old.Minute, old.Second, old.Kind).AddMinutes(Interval); break; case FrequencyType.HOURLY: dt.Value = new DateTime(old.Year, old.Month, old.Day, old.Hour, old.Minute, old.Second, old.Kind).AddHours(Interval); break; case FrequencyType.DAILY: dt.Value = new DateTime(old.Year, old.Month, old.Day, old.Hour, old.Minute, old.Second, old.Kind).AddDays(Interval); break; case FrequencyType.WEEKLY: // How the week increments depends on the WKST indicated (defaults to Monday) // So, basically, we determine the week of year using the necessary rules, // and we increment the day until the week number matches our "goal" week number. // So, if the current week number is 36, and our Interval is 2, then our goal // week number is 38. // NOTE: fixes RRULE12 eval. int current = m_Calendar.GetWeekOfYear(old, System.Globalization.CalendarWeekRule.FirstFourDayWeek, Wkst), last = m_Calendar.GetWeekOfYear(new DateTime(old.Year, 12, 31, 0, 0, 0, DateTimeKind.Local), System.Globalization.CalendarWeekRule.FirstFourDayWeek, Wkst), goal = current + Interval; // If the goal week is greater than the last week of the year, wrap it! if (goal > last) { goal = goal - last; } while (current != goal) { old = old.AddDays(1); current = m_Calendar.GetWeekOfYear(old, System.Globalization.CalendarWeekRule.FirstFourDayWeek, Wkst); } dt.Value = old; break; case FrequencyType.MONTHLY: dt.Value = new DateTime(old.Year, old.Month, 1, old.Hour, old.Minute, old.Second, old.Kind).AddMonths(Interval); break; case FrequencyType.YEARLY: dt.Value = new DateTime(old.Year, 1, 1, old.Hour, old.Minute, old.Second, old.Kind).AddYears(Interval); break; default: throw new Exception("IncrementDate() failed."); } }
/// <summary> /// Retrieves the TimeZoneInfo object that contains information /// about the TimeZone, with the name of the current timezone, /// offset from UTC, etc. /// </summary> /// <param name="dt">The Date_Time object for which to retrieve the TimeZoneInfo</param> /// <returns>A TimeZoneInfo object for the specified Date_Time</returns> public TimeZoneInfo GetTimeZoneInfo(Date_Time dt) { TimeZoneInfo tzi = null; TimeSpan mostRecent = TimeSpan.MaxValue; foreach (TimeZoneInfo curr in TimeZoneInfos) { DateTime Start = new DateTime(dt.Year - 1, 1, 1, 0, 0, 0, DateTimeKind.Utc); DateTime End = new DateTime(dt.Year + 1, 1, 1, 0, 0, 0, DateTimeKind.Utc); DateTime dtUTC = dt.Value; dtUTC = DateTime.SpecifyKind(dtUTC, DateTimeKind.Utc); if (curr.TZOffsetTo != null) { int mult = curr.TZOffsetTo.Positive ? -1 : 1; dtUTC = dtUTC.AddHours(curr.TZOffsetTo.Hours * mult); dtUTC = dtUTC.AddMinutes(curr.TZOffsetTo.Minutes * mult); dtUTC = dtUTC.AddSeconds(curr.TZOffsetTo.Seconds * mult); curr.Start = curr.Start.AddHours(curr.TZOffsetTo.Hours * mult); curr.Start = curr.Start.AddMinutes(curr.TZOffsetTo.Minutes * mult); curr.Start = curr.Start.AddSeconds(curr.TZOffsetTo.Seconds * mult); } // Determine the UTC occurrences of the Time Zone changes // FIXME: are these start/end dates correct when TimeZone or UTC time is taken into account? if (curr.EvalStart == null || curr.EvalEnd == null || dtUTC < curr.EvalStart.Value || dtUTC > curr.EvalEnd.Value) curr.Evaluate(Start, End); foreach (Date_Time currDt in curr.DateTimes) { TimeSpan currentSpan = dtUTC - currDt; if (currentSpan.Ticks >= 0 && currentSpan.Ticks < mostRecent.Ticks) { mostRecent = currentSpan; tzi = curr; } } } return tzi; }
public override bool TryParse(string value, ref object obj) { string[] values = value.Split(','); foreach (string v in values) { object dt = new Date_Time(); object p = new Period(); iCalendar iCal = null; if (ContentLine != null) { iCal = ContentLine.iCalendar; } // // Set the iCalendar for each Date_Time object here, // so that any time zones applied to these objects will be // handled correctly. // NOTE: fixes RRULE30 eval, where EXDATE references a // DATE-TIME without a time zone; therefore, the time zone // is implied from DTSTART, and would fail to do a proper // time zone lookup, because it wasn't assigned an iCalendar // object. // if (((Date_Time)dt).TryParse(v, ref dt)) { ((Date_Time)dt).iCalendar = iCal; ((Date_Time)dt).TZID = TZID; Items.Add(dt); } else if (((Period)p).TryParse(v, ref p)) { ((Period)p).StartTime.iCalendar = ((Period)p).EndTime.iCalendar = iCal; ((Period)p).StartTime.TZID = ((Period)p).EndTime.TZID = TZID; Items.Add(p); } else { return(false); } } return(true); }
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 void LoadAndDisplayCalendar() { // The following code loads and displays an iCalendar // with US Holidays for 2006. // iCalendar iCal = iCalendar.LoadFromFile(@"Calendars\General\USHolidays.ics"); Assert.IsNotNull(iCal, "iCalendar did not load. Are you connected to the internet?"); iCal.Evaluate( new Date_Time(2006, 1, 1, "US-Eastern", iCal), new Date_Time(2006, 12, 31, "US-Eastern", iCal)); Date_Time dt = new Date_Time(2006, 1, 1, "US-Eastern", iCal); while (dt.Year == 2006) { // First, display the current date we're evaluating Console.WriteLine(dt.Local.ToShortDateString()); // Then, iterate through each event in our iCalendar foreach (Event evt in iCal.Events) { // Determine if the event occurs on the specified date if (evt.OccursOn(dt)) { // Display the event summary Console.Write("\t" + evt.Summary); // Display the time the event happens (unless it's an all-day event) if (evt.Start.HasTime) { Console.Write(" (" + evt.Start.Local.ToShortTimeString() + " - " + evt.End.Local.ToShortTimeString()); if (evt.Start.TimeZoneInfo != null) Console.Write(" " + evt.Start.TimeZoneInfo.TimeZoneName); Console.Write(")"); } Console.Write(Environment.NewLine); } } // Move to the next day dt = dt.AddDays(1); } }
public void LoadAndDisplayCalendar() { iCalendar iCal = iCalendar.LoadFromFile(@"Calendars/USHolidays.ics"); foreach (Event evt in iCal.Events) evt.Evaluate(new Date_Time(2006, 1, 1, "/mozilla.org/20050126_1/America/Boise", iCal), new Date_Time(2006, 12, 31, "/mozilla.org/20050126_1/America/Boise", iCal)); Date_Time dt = new Date_Time(2006, 1, 1, "/mozilla.org/20050126_1/America/Boise", iCal); while (dt.Year == 2006) { Console.WriteLine(dt.Local.ToShortDateString()); foreach (Event evt in iCal.Events) { if (evt.OccursOn(dt)) Console.WriteLine("\t" + evt.Summary + (evt.DTStart.HasTime ? " (" + evt.DTStart.Local.ToShortTimeString() + " - " + evt.DTEnd.Local.ToShortTimeString() + " " + (evt.DTStart.TimeZoneInfo != null ? evt.DTStart.TimeZoneInfo.TZName[0] : "") + ")" : "")); } dt = dt.AddDays(1); } }
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 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 ArrayList Evaluate(Date_Time StartDate, Date_Time FromDate, Date_Time EndDate) { ArrayList Periods = new ArrayList(); if (StartDate > FromDate) { FromDate = StartDate; } if (EndDate < FromDate || FromDate > EndDate) { return(Periods); } foreach (object obj in Items) { Periods.Add(obj); } return(Periods); }
public override bool TryParse(string value, ref object obj) { string[] values = value.Split(','); foreach (string v in values) { object dt = new Date_Time(); object p = new Period(); if (((Date_Time)dt).TryParse(v, ref dt)) { Items.Add(dt); } else if (((Period)p).TryParse(v, ref p)) { Items.Add(p); } else { return(false); } } return(true); }
/// <summary> /// Evaluates this item to determine the dates and times for which it occurs/recurs. /// This method only evaluates items which occur/recur between <paramref name="FromDate"/> /// and <paramref name="ToDate"/>; therefore, if you require a list of items which /// occur outside of this range, you must specify a <paramref name="FromDate"/> and /// <paramref name="ToDate"/> which encapsulate the date(s) of interest. /// <note type="caution"> /// For events with very complex recurrence rules, this method may be a bottleneck /// during processing time, especially when this method is called for a large number /// of items, in sequence, or for a very large time span. /// </note> /// </summary> /// <param name="FromDate">The beginning date of the range to evaluate.</param> /// <param name="ToDate">The end date of the range to evaluate.</param> /// <returns> /// An <see cref="ArrayList"/> containing a <see cref="Date_Time"/> object for /// each date/time this item occurs/recurs. /// </returns> virtual public ArrayList Evaluate(Date_Time FromDate, Date_Time ToDate) { // Evaluate extra time periods, without re-evaluating ones that were already evaluated if ((EvalStart == null && EvalEnd == null) || (ToDate == EvalStart) || (FromDate == EvalEnd)) { EvaluateRRule(FromDate, ToDate); EvaluateRDate(FromDate, ToDate); EvaluateExRule(FromDate, ToDate); EvaluateExDate(FromDate, ToDate); if (EvalStart == null || EvalStart > FromDate) EvalStart = FromDate.Copy(); if (EvalEnd == null || EvalEnd < ToDate) EvalEnd = ToDate.Copy(); } if (EvalStart != null && FromDate < EvalStart) Evaluate(FromDate, EvalStart); if (EvalEnd != null && ToDate > EvalEnd) Evaluate(EvalEnd, ToDate); return DateTimes; }
public Period(Date_Time occurs) : this(occurs, null) { }
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 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 Date_Time(Date_Time value) : this() { CopyFrom(value); }
public Date_Time(Date_Time value) : this(value.Value) { }
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 Date_Time(Date_Time value) { CopyFrom(value); }
public void MERGE() { iCalendar iCal1 = iCalendar.LoadFromFile(@"Calendars\Recurrence\RRULE21.ics"); iCalendar iCal2 = iCalendar.LoadFromFile(@"Calendars\Recurrence\RRULE22.ics"); iCal1.MergeWith(iCal2); Event evt1 = iCal1.Events[0]; Event evt2 = iCal1.Events[1]; evt1.Evaluate(new Date_Time(1996, 1, 1, tzid, iCal1), new Date_Time(2000, 1, 1, tzid, iCal1)); Date_Time[] DateTimes = new Date_Time[] { new Date_Time(1997, 9, 10, 9, 0, 0, tzid, iCal1), new Date_Time(1997, 9, 11, 9, 0, 0, tzid, iCal1), new Date_Time(1997, 9, 12, 9, 0, 0, tzid, iCal1), new Date_Time(1997, 9, 13, 9, 0, 0, tzid, iCal1), new Date_Time(1997, 9, 14, 9, 0, 0, tzid, iCal1), new Date_Time(1997, 9, 15, 9, 0, 0, tzid, iCal1), new Date_Time(1999, 3, 10, 9, 0, 0, tzid, iCal1), new Date_Time(1999, 3, 11, 9, 0, 0, tzid, iCal1), new Date_Time(1999, 3, 12, 9, 0, 0, tzid, iCal1), new Date_Time(1999, 3, 13, 9, 0, 0, tzid, iCal1), }; string[] TimeZones = new string[] { "EDT", "EDT", "EDT", "EDT", "EDT", "EDT", "EST", "EST", "EST", "EST" }; for (int i = 0; i < DateTimes.Length; i++) { Date_Time dt = (Date_Time)DateTimes[i]; Assert.IsTrue(evt1.OccursAt(dt), "Event should occur on " + dt); Assert.IsTrue(dt.TimeZoneInfo.TimeZoneName == TimeZones[i], "Event " + dt + " should occur in the " + TimeZones[i] + " timezone"); } Assert.IsTrue(evt1.Periods.Count == DateTimes.Length, "There should be exactly " + DateTimes.Length + " occurrences; there were " + evt1.Periods.Count); evt2.Evaluate(new Date_Time(1996, 1, 1, tzid, iCal1), new Date_Time(1998, 4, 1, tzid, iCal1)); Date_Time[] DateTimes1 = new Date_Time[] { new Date_Time(1997, 9, 2, 9, 0, 0, tzid, iCal1), new Date_Time(1997, 9, 9, 9, 0, 0, tzid, iCal1), new Date_Time(1997, 9, 16, 9, 0, 0, tzid, iCal1), new Date_Time(1997, 9, 23, 9, 0, 0, tzid, iCal1), new Date_Time(1997, 9, 30, 9, 0, 0, tzid, iCal1), new Date_Time(1997, 11, 4, 9, 0, 0, tzid, iCal1), new Date_Time(1997, 11, 11, 9, 0, 0, tzid, iCal1), new Date_Time(1997, 11, 18, 9, 0, 0, tzid, iCal1), new Date_Time(1997, 11, 25, 9, 0, 0, tzid, iCal1), new Date_Time(1998, 1, 6, 9, 0, 0, tzid, iCal1), new Date_Time(1998, 1, 13, 9, 0, 0, tzid, iCal1), new Date_Time(1998, 1, 20, 9, 0, 0, tzid, iCal1), new Date_Time(1998, 1, 27, 9, 0, 0, tzid, iCal1), new Date_Time(1998, 3, 3, 9, 0, 0, tzid, iCal1), new Date_Time(1998, 3, 10, 9, 0, 0, tzid, iCal1), new Date_Time(1998, 3, 17, 9, 0, 0, tzid, iCal1), new Date_Time(1998, 3, 24, 9, 0, 0, tzid, iCal1), new Date_Time(1998, 3, 31, 9, 0, 0, tzid, iCal1) }; string[] TimeZones1 = new string[] { "EDT", "EDT", "EDT", "EDT", "EDT", "EST", "EST", "EST", "EST", "EST", "EST", "EST", "EST", "EST", "EST", "EST", "EST", "EST" }; for (int i = 0; i < DateTimes1.Length; i++) { Date_Time dt = (Date_Time)DateTimes1[i]; Assert.IsTrue(evt2.OccursAt(dt), "Event should occur on " + dt); Assert.IsTrue(dt.TimeZoneInfo.TimeZoneName == TimeZones1[i], "Event " + dt + " should occur in the " + TimeZones1[i] + " timezone"); } Assert.IsTrue(evt2.Periods.Count == DateTimes1.Length, "There should be exactly " + DateTimes1.Length + " occurrences; there were " + evt2.Periods.Count); }
public Date_TimeSerializer(Date_Time dt) : base(dt) { this.m_DateTime = dt; }
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); }
protected void IncrementDate(Date_Time dt) { IncrementDate(dt, this.Interval); }
public bool CheckValidDate(Date_Time dt) { if (BySecond.Count != 0 && !BySecond.Contains(dt.Value.Second)) { return(false); } if (ByMinute.Count != 0 && !ByMinute.Contains(dt.Value.Minute)) { return(false); } if (ByHour.Count != 0 && !ByHour.Contains(dt.Value.Hour)) { return(false); } if (ByDay.Count != 0) { bool found = false; foreach (DaySpecifier bd in ByDay) { if (bd.CheckValidDate(this, dt)) { found = true; break; } } if (!found) { return(false); } } if (ByWeekNo.Count != 0) { bool found = false; int lastWeekOfYear = m_Calendar.GetWeekOfYear(new DateTime(dt.Value.Year, 12, 31), System.Globalization.CalendarWeekRule.FirstFourDayWeek, Wkst); int currWeekNo = m_Calendar.GetWeekOfYear(dt.Value, System.Globalization.CalendarWeekRule.FirstFourDayWeek, Wkst); foreach (int WeekNo in ByWeekNo) { if ((WeekNo > 0 && WeekNo == currWeekNo) || (WeekNo < 0 && lastWeekOfYear + WeekNo + 1 == currWeekNo)) { found = true; } } if (!found) { return(false); } } if (ByMonth.Count != 0 && !ByMonth.Contains(dt.Value.Month)) { return(false); } if (ByMonthDay.Count != 0) { // Handle negative days of month (count backwards from the end) // NOTE: fixes RRULE18 eval bool found = false; int DaysInMonth = m_Calendar.GetDaysInMonth(dt.Value.Year, dt.Value.Month); foreach (int Day in ByMonthDay) { if ((Day > 0) && (Day == dt.Value.Day)) { found = true; } else if ((Day < 0) && (DaysInMonth + Day + 1 == dt.Value.Day)) { found = true; } } if (!found) { return(false); } } if (ByYearDay.Count != 0) { // Handle negative days of year (count backwards from the end) // NOTE: fixes RRULE25 eval bool found = false; int DaysInYear = m_Calendar.GetDaysInYear(dt.Value.Year); DateTime baseDate = new DateTime(dt.Value.Year, 1, 1); foreach (int Day in ByYearDay) { if (Day > 0 && dt.Value.Date == baseDate.AddDays(Day - 1)) { found = true; } else if (Day < 0 && dt.Value.Date == baseDate.AddYears(1).AddDays(Day)) { found = true; } } if (!found) { return(false); } } return(true); }
public void RRULE18() { iCalendar iCal = iCalendar.LoadFromFile(@"Calendars\Recurrence\RRULE18.ics"); Program.TestCal(iCal); Event evt = iCal.Events[0]; List<Occurrence> occurrences = evt.GetOccurrences( new Date_Time(1996, 1, 1, tzid, iCal), new Date_Time(1998, 3, 1, tzid, iCal)); Date_Time[] DateTimes = new Date_Time[] { new Date_Time(1997, 9, 28, 9, 0, 0, tzid, iCal), new Date_Time(1997, 10, 29, 9, 0, 0, tzid, iCal), new Date_Time(1997, 11, 28, 9, 0, 0, tzid, iCal), new Date_Time(1997, 12, 29, 9, 0, 0, tzid, iCal), new Date_Time(1998, 1, 29, 9, 0, 0, tzid, iCal), new Date_Time(1998, 2, 26, 9, 0, 0, tzid, iCal) }; string[] TimeZones = new string[] { "EDT", "EST", "EST", "EST", "EST", "EST" }; for (int i = 0; i < DateTimes.Length; i++) { Date_Time dt = (Date_Time)DateTimes[i]; Assert.AreEqual(dt, occurrences[i].Period.StartTime, "Event should occur on " + dt); Assert.AreEqual(TimeZones[i], dt.TimeZoneInfo.TimeZoneName, "Event " + dt + " should occur in the " + TimeZones[i] + " timezone"); } Assert.AreEqual( DateTimes.Length, occurrences.Count, "There should be exactly " + DateTimes.Length + " occurrences; there were " + occurrences.Count); }
protected List <Date_Time> CalculateChildOccurrences(Date_Time StartDate, Date_Time EndDate) { TimeCalculation TC = new TimeCalculation(StartDate, EndDate, this); switch (Frequency) { case FrequencyType.YEARLY: FillYearDays(TC); FillByDay(TC); FillMonths(TC); break; case FrequencyType.WEEKLY: // Weeks can span across months, so we must fill months (Note: fixes RRULE10 eval) FillMonths(TC); break; case FrequencyType.MONTHLY: FillDays(TC); FillByDay(TC); break; case FrequencyType.DAILY: FillHours(TC); break; case FrequencyType.HOURLY: FillMinutes(TC); break; case FrequencyType.MINUTELY: FillSeconds(TC); break; default: throw new NotSupportedException("CalculateChildOccurrences() is not supported for a frequency of " + Frequency.ToString()); } // Apply the BYSETPOS to the list of child occurrences // We do this before the dates are filtered by Start and End date // so that the BYSETPOS calculates correctly. // NOTE: fixes RRULE33 eval if (BySetPos.Count != 0) { List <Date_Time> newDateTimes = new List <Date_Time>(); foreach (int pos in BySetPos) { if (Math.Abs(pos) <= TC.DateTimes.Count) { if (pos > 0) { newDateTimes.Add(TC.DateTimes[pos - 1]); } else if (pos < 0) { newDateTimes.Add(TC.DateTimes[TC.DateTimes.Count + pos]); } } } TC.DateTimes = newDateTimes; } // Filter dates by Start and End date for (int i = TC.DateTimes.Count - 1; i >= 0; i--) { if ((Date_Time)TC.DateTimes[i] < StartDate || (Date_Time)TC.DateTimes[i] > EndDate) { TC.DateTimes.RemoveAt(i); } } return(TC.DateTimes); }
/// <summary> /// Evaluates component recurrences for the given range of time. /// <example> /// For example, if you are displaying a month-view for January 2007, /// you would want to evaluate recurrences for Jan. 1, 2007 to Jan. 31, 2007 /// to display relevant information for those dates. /// </example> /// </summary> /// <param name="FromDate">The beginning date/time of the range to test.</param> /// <param name="ToDate">The end date/time of the range to test.</param> public void Evaluate(Date_Time FromDate, Date_Time ToDate) { foreach (iCalObject obj in Children) { if (obj is RecurringComponent) ((RecurringComponent)obj).Evaluate(FromDate, ToDate); } }
public void Remove(Date_Time dt) { Periods.Remove(new Period(dt)); }
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 Add(Date_Time dt) { Periods.Add(new Period(dt)); }