static public List <DateTime> GetReccurence(String rrule, DateTime dtStart, DateTime dtEnd) { //DAILY //"FREQ=DAILY; INTERVAL=2;"; //"FREQ=DAILY;" //RRULE:FREQ=DAILY;INTERVAL=10;COUNT=3; //WEEKLY //FREQ=WEEKLY;COUNT=10 //FREQ=WEEKLY; //FREQ=WEEKLY;INTERVAL=2 //FREQ=WEEKLY;COUNT=10;BYDAY=TU,TH //FREQ=WEEKLY;INTERVAL=2;COUNT=8;WKST=SU;BYDAY=TU,TH //MONTHLY //FREQ=MONTHLY;COUNT=10;BYDAY=FR;SETPOS=1 //FREQ=MONTHLY;INTERVAL=2;COUNT=10;BYDAY=SU;SETPOS=1,-1 первое и последнее воскресенье месяца //FREQ=MONTHLY;COUNT=6;BYDAY=MO;SETPOS=-2 //FREQ=MONTHLY;BYMONTHDAY=-3 //FREQ=MONTHLY;COUNT=10;BYMONTHDAY=2,15 //FREQ=MONTHLY;COUNT=10;BYMONTHDAY=1,-1 //FREQ=MONTHLY;INTERVAL=18;COUNT=10;BYMONTHDAY=10,11,12,13,14,15 //FREQ=MONTHLY;INTERVAL=2;BYDAY=TU //FREQ=MONTHLY;BYDAY=FR;BYMONTHDAY=13 //FREQ=MONTHLY;COUNT=3;BYDAY=TU,WE,TH;BYSETPOS=3 //FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-2 - пердпослений рабочий день месяца //FREQ=MONTHLY;BYDAY=MO;BYSETPOS=-1 - последний понедельник месяца //FREQ=MONTHLY;COUNT=9;BYDAY=1MO, 3MO, 5MO; - каждый 2-й понедельник месяца //FREQ=MONTHLY;COUNT=9;BYDAY=MO;SETPOS=1,3,5 - Каждый второй понедельник месяцв //YEARLY //FREQ=YEARLY;BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA //FREQ=YEARLY;COUNT=10;BYYEARDAY=1,-1 //FREQ=YEARLY;COUNT=10;BYMONTH=6,7 //FREQ=YEARLY;INTERVAL=3;COUNT=10;BYYEARDAY=1,100,200 //FREQ=YEARLY;COUNT=10;BYYEARDAY=366, -366 //FREQ=YEARLY;BYDAY=MO;SETPOS=20 //FREQ=YEARLY;BYWEEKNO=20;BYDAY=MO //FREQ=YEARLY;BYMONTH=3;BYDAY=TH //FREQ=YEARLY;INTERVAL=1;BYMONTH=1;BYDAY=TU;BYMONTHDAY=1,2,3,4,5,6;WEEKNO=1;BYYEARDAY=3 //String rrule = "FREQ=YEARLY;BYDAY=MO;SETPOS=52"; RruleParam param = RruleParse(rrule); param.DTStart = dtStart; param.DTEnd = dtEnd; return(param.GetRecurringDates()); }
//Util methods static private RruleParam RruleParse(string rrule) { RruleParam retVal = new RruleParam(); StringBuilder regExpBld = new StringBuilder(); regExpBld.Append("(?:FREQ=(?<FREQ>[^;]+)|"); regExpBld.Append("COUNT=(?<COUNT>[^;]+)|"); regExpBld.Append("INTERVAL=(?<INTERVAL>[^;]+)|"); regExpBld.Append("WKST=(?<WKST>[^;]+)|"); regExpBld.Append("SETPOS=(?<SETPOS>[^;]+)|"); regExpBld.Append("BYMONTH=(?<BYMONTH>[^;]+)|"); regExpBld.Append("INTERVAL=(?<INTERVAL>[^;]+)|"); regExpBld.Append("BYDAY=(?<BYDAY>[^;]+)|"); regExpBld.Append("BYMONTHDAY=(?<BYMONTHDAY>[^;]+)|"); regExpBld.Append("BYWEEKNO=(?<BYWEEKNO>[^;]+)|"); regExpBld.Append("BYYEARDAY=(?<BYYEARDAY>[^;]+))"); Regex rruleParser = new Regex(regExpBld.ToString()); MatchCollection matches = rruleParser.Matches(rrule); foreach (Match match in matches) { string capture = match.Groups["FREQ"].Value; if (!String.IsNullOrEmpty(capture)) { if (capture.Equals("DAILY", StringComparison.InvariantCultureIgnoreCase)) { retVal.freqHandler = Daily; } else if (capture.Equals("WEEKLY", StringComparison.InvariantCultureIgnoreCase)) { retVal.freqHandler = Weekly; } else if (capture.Equals("MONTHLY", StringComparison.InvariantCultureIgnoreCase)) { retVal.freqHandler = Monthly; } else if (capture.Equals("YEARLY", StringComparison.InvariantCultureIgnoreCase)) { retVal.freqHandler = Yearly; } else { throw new ArgumentException("FREQ"); } } capture = match.Groups["COUNT"].Value; if (!String.IsNullOrEmpty(capture)) { retVal.Count = Convert.ToInt32(capture); } capture = match.Groups["INTERVAL"].Value; if (!String.IsNullOrEmpty(capture)) { retVal.Interval = Convert.ToInt32(capture); } capture = match.Groups["SETPOS"].Value; if (!String.IsNullOrEmpty(capture)) { retVal.Setpos = ConvertParam <int>(capture); } capture = match.Groups["WKST"].Value; if (!String.IsNullOrEmpty(capture)) { retVal.WkST = ConvertParam <DayOfWeek>(capture)[0]; } capture = match.Groups["BYMONTH"].Value; if (!String.IsNullOrEmpty(capture)) { retVal.byMonth = ConvertParam <int>(capture); } capture = match.Groups["BYDAY"].Value; if (!String.IsNullOrEmpty(capture)) { retVal.ByDay = ConvertParam <DayOfWeek>(capture); } capture = match.Groups["BYMONTHDAY"].Value; if (!String.IsNullOrEmpty(capture)) { retVal.byMonthDay = ConvertParam <int>(capture); } capture = match.Groups["BYWEEKNO"].Value; if (!String.IsNullOrEmpty(capture)) { retVal.byWeekno = ConvertParam <int>(capture); } capture = match.Groups["BYYEARDAY"].Value; if (!String.IsNullOrEmpty(capture)) { retVal.byYearDay = ConvertParam <int>(capture); } } return(retVal); }
static private List <DateTime> Daily(RruleParam param) { return(Daily(param.Count, param.Interval, param.DTStart, param.DTEnd)); }
static private List <DateTime> Weekly(RruleParam param) { return(Weekly(param.Count, param.Interval, param.ByDay, param.DTStart, param.DTEnd)); }
static private List <DateTime> Monthly(RruleParam param) { return(Monthly(param.Count, param.Interval, param.Setpos, param.byMonthDay, param.ByDay, param.DTStart, param.DTEnd)); }
static private List <DateTime> Yearly(RruleParam param) { return(Yearly(param.Count, param.Interval, param.Setpos, param.ByDay, param.WkST, param.byMonthDay, param.byYearDay, param.byMonth, param.byWeekno, param.DTStart, param.DTEnd)); }