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