最近在做一個關於Calendar的項目,相當於Google Calendar或者Outlook中的Calendar。在Calendar的發布和共享中,使用到了iCalendar,是一種日歷數據交換的標准,具體參見維基百科:http://zh.wikipedia.org/wiki/ICalendar
由於使用C#開發,所以希望能夠找到一個開源或者免費的iCalendar組件,幫助生成.ics格式的文件。果然有人做了這樣的事情,那就是DDay.iCal,開源地址:http://sourceforge.net/projects/dday-ical/
關於Calendar,普通的事件都好設置,最麻煩的就是循環事件。循環事件有多個屬性需要設置,還要計算接下來發生的時間,但是在iCalendar標准中,這些循環設置,最終都化作為一個RRule格式的字符串(關於RRule格式的標准,我們可以參見http://www.kanzaki.com/docs/ical/rrule.html)。
既然是以DDay.iCal來生成ics文件,那麼想必這個組件也有解析RRule格式和生成RRule格式的方法。下面就說說如果使用DDay.iCal處理RRule。
一、RRule的解析
DDay.iCal中有個RecurrencePattern對象,該對象可以用於描述循環設置。該對象在構造時可以傳入RRule字符串,然後我們可以使用RecurringComponent對象的GetOccurrences方法獲得循環事件在指定時間區間內的發生的時間。
閒話休說,我們看代碼:
RecurringComponent recurringComponent = new RecurringComponent(); RecurrencePattern pattern = new RecurrencePattern("FREQ=WEEKLY;BYDAY=MO");//RRule設置為每周一發生 recurringComponent.RecurrenceRules.Add(pattern); recurringComponent.Start = new iCalDateTime(Convert.ToDateTime("2013-6-1 00:00:00")); //該循環事件從6.1開始發生 var occurrences = recurringComponent.GetOccurrences( Convert.ToDateTime("2013-6-30 23:59:59"), //我們雖然要取的是7.1號之後的事件,但是這裡不能寫成2013-7-1,因為該函數在計算時是>startTime <=endTime Convert.ToDateTime("2013-7-31 23:59:59")); //獲得循環事件在7月份發生的具體時間 foreach (Occurrence occurrence in occurrences) { DateTime occurrenceTime = occurrence.Period.StartTime.Local; Console.WriteLine(occurrenceTime.ToString("yyyy-MM-dd")); }
二、RRule的生成
RRule還是通過RecurrencePattern來設置循環的屬性,然後使用ToString方法就能夠獲得RRule字符串了。
代碼如下:
RecurrencePattern pattern = new RecurrencePattern(); pattern.ByDay=new List<IWeekDay>(){new WeekDay(DayOfWeek.Sunday)};//每周周日發生 pattern.Frequency=FrequencyType.Weekly;//循環周期為周 Console.WriteLine(pattern.ToString());//生成RRule格式的字符串 RecurringComponent recurringComponent = new RecurringComponent(); recurringComponent.RecurrenceRules.Add(pattern); recurringComponent.Start = new iCalDateTime(Convert.ToDateTime("2013-6-1 00:00:00")); //該循環事件從6.1開始發生 var occurrences = recurringComponent.GetOccurrences( Convert.ToDateTime("2013-6-30 23:59:59"), //我們雖然要取的是7.1號之後的事件,但是這裡不能寫成2013-7-1,因為該函數在計算時是>startTime <=endTime Convert.ToDateTime("2013-7-31 23:59:59")); //獲得循環事件在7月份發生的具體時間 foreach (Occurrence occurrence in occurrences) { DateTime occurrenceTime = occurrence.Period.StartTime.Local; Console.WriteLine(occurrenceTime.ToString("yyyy-MM-dd")); }