Пример #1
0
        /// <summary>
        /// This is used to expand one or more months by day of the week.  It is used by the monthly and yearly
        /// frequencies.
        /// </summary>
        /// <param name="r">A reference to the recurrence</param>
        /// <param name="dates">A reference to the collection of current instances that have been generated</param>
        /// <returns>The number of instances in the collection.  If zero, subsequent rules don't have to be
        /// checked as there's nothing else to do.</returns>
        /// <remarks>If an expanded date is invalid, it will be discarded</remarks>
        public static int ByDayInMonths(Recurrence r, RecurDateTimeCollection dates)
        {
            RecurDateTime rdt, rdtNew;
            DayOfWeek     dow;
            int           expIdx, instance, count = dates.Count;

            DayInstanceCollection byDay = r.ByDay;

            // Don't bother if either collection is empty
            if (count != 0 && byDay.Count != 0)
            {
                for (int idx = 0; idx < count; idx++)
                {
                    rdt = dates[0];
                    dates.RemoveAt(0);

                    // Expand the date/time by adding a new entry for each week day instance specified
                    for (expIdx = 0; expIdx < byDay.Count; expIdx++)
                    {
                        instance = byDay[expIdx].Instance;
                        dow      = byDay[expIdx].DayOfWeek;

                        if (instance == 0)
                        {
                            // Expand to every specified day of the week
                            // in the month.
                            rdtNew = new RecurDateTime(rdt)
                            {
                                Day = 1
                            };

                            rdtNew.AddDays(((int)dow + 7 - (int)rdtNew.DayOfWeek) % 7);

                            while (rdtNew.IsValidDate() && rdtNew.Year == rdt.Year && rdtNew.Month == rdt.Month)
                            {
                                dates.Add(new RecurDateTime(rdtNew));
                                rdtNew.AddDays(7);
                            }

                            continue;
                        }

                        if (instance > 0)
                        {
                            // Add the nth instance of the day of the week
                            rdtNew = new RecurDateTime(rdt)
                            {
                                Day = 1
                            };

                            rdtNew.AddDays((((int)dow + 7 - (int)rdtNew.DayOfWeek) % 7) + ((instance - 1) * 7));
                        }
                        else
                        {
                            // Add the nth instance of the day of the week
                            // from the end of the month.
                            rdtNew = new RecurDateTime(rdt)
                            {
                                Day = DateTime.DaysInMonth(rdt.Year, rdt.Month + 1)
                            };

                            rdtNew.AddDays(0 - (((int)rdtNew.DayOfWeek + 7 - (int)dow) % 7) + ((instance + 1) * 7));
                        }

                        // If not in the year, discard it
                        if (rdtNew.Year != rdt.Year || rdtNew.Month != rdt.Month)
                        {
                            continue;
                        }

                        dates.Add(new RecurDateTime(rdtNew));
                    }
                }
            }

            return(dates.Count);
        }