最近在做一個關於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")); }