Example #1
0
            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 });
                    }
                }
            }
Example #2
0
 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));
 }
Example #3
0
 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;
     }
 }
Example #4
0
        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;  
        }
Example #5
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);
            }
Example #6
0
        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;
            }
        }
Example #7
0
 public RecurSerializer(Recur recur)
     : base(recur)
 {
     this.m_Recur = recur;
 }
Example #8
0
 public RecurSerializer(DDay.iCal.DataTypes.Recur recur)
     : base(recur)
 {
     this.m_Recur = recur;
 }
Example #9
0
        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;
        }
Example #10
0
        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 { }
        }
Example #11
0
 private void DetermineStartingRecurrence(Recur recur, ref Date_Time dt)
 {
     if (recur.Count != int.MinValue)
         dt = DTStart.Copy();
     else recur.IncrementDate(dt, -recur.Interval);
 }
Example #12
0
            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 });
                }
            }
Example #13
0
 public RecurSerializer(Recur recur)
     : base(recur)
 {
     this.m_Recur = recur;
 }
 public DaySpecifierSerializer(Recur.DaySpecifier byday)
     : base(byday)
 {
     this.m_DaySpecifier = byday;
 }
Example #15
0
        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);
        }
Example #16
0
        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);
        }
Example #17
0
        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);
        }
Example #18
0
        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);
        }
Example #19
0
        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");
        }
Example #20
0
        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);
        }
Example #21
0
        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);
        }
Example #22
0
        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;
        }
Example #23
0
        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);
        }
Example #24
0
        //[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));
        }
Example #25
0
        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 };
        }
Example #27
0
        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 };
 }
Example #29
0
 public RecurSerializer(DDay.iCal.DataTypes.Recur recur)
     : base(recur)
 {
     this.m_Recur = recur;
 }
Example #30
0
            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;
            }
Example #31
0
        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);
        }
Example #32
0
            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);
            }
Example #33
0
        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");
        }
Example #34
0
        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;
        }