2012-07-11 48 views
2

我需要解析Google日曆中的重複事件值。我能夠解析除重複對象值之外的其餘值。以下是我試圖拉從谷歌日曆事件在我的asp.net MVC(C#)應用程序的代碼:如何解析Google日曆Feed,包括.net中的重複事件

GOAuthRequestFactory authFactory = new GOAuthRequestFactory("cl", "MyApp"); 
authFactory.ConsumerKey = ConfigurationManager.AppSettings["GConsumerKey"].ToString(); 
authFactory.ConsumerSecret = ConfigurationManager.AppSettings["GConsumerKeySecret"].ToString(); 
authFactory.Token = "myGoogleToken"; 
authFactory.TokenSecret = "myGoogleTokenSecret"; 
Google.GData.Calendar.CalendarService service = new Google.GData.Calendar.CalendarService(authFactory.ApplicationName); 
service.RequestFactory = authFactory; 

Uri postUri = new Uri("https://www.google.com/calendar/feeds/default/private/full"); 

EventQuery myQuery = new EventQuery(postUri.ToString()); 
myQuery.StartTime = DateTime.Now; 

EventFeed myResultsFeed = service.Query(myQuery); 
if (myResultsFeed.Entries.Count > 0) 
{ 
    foreach (EventEntry eve in myResultsFeed.Entries) 
    { 
     #region Declaration 
     string w = string.Empty; string desc = string.Empty;       
     #endregion 

     #region Title/Description 
     //Title 
     if (eve.Title != null) 
     { 
      AtomTextConstruct _construct = eve.Title; 
      if (_construct != null) 
      { 
       w = _construct.Text; 
      } 
     } 
     //Description 
     if (eve.Content != null) 
     { 
      AtomContent _content = eve.Content; 
      if (_content.Content != null) 
      { 
       desc = Utility.GetValueFromMaxLength(_content.Content, 1000); 
      } 
     } 
     #endregion 

     if (eve.Recurrence != null) 
     { 
      Recurrence _recurrence = eve.Recurrence; 
      if (_recurrence != null && !string.IsNullOrEmpty(_recurrence.Value)) 
      { 

      } 
     } 
    } 
} 

復發的價值是:

DTSTART;TZID=America/New_York:20120710T090000 
DTEND;TZID=America/New_York:20120710T093000 
RRULE:FREQ=WEEKLY;BYDAY=TU 
BEGIN:VTIMEZONE 
TZID:America/New_York 
X-LIC-LOCATION:America/New_York 
BEGIN:DAYLIGHT 
TZOFFSETFROM:-0500 
TZOFFSETTO:-0400 
TZNAME:EDT 
DTSTART:19700308T020000 
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU 
END:DAYLIGHT 
BEGIN:STANDARD 
TZOFFSETFROM:-0400 
TZOFFSETTO:-0500 
TZNAME:EST 
DTSTART:19701101T020000 
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU 
END:STANDARD 
END:VTIMEZONE 

如何可以解析這個重複元素值?請建議。

+0

我在JavaScript中有同樣的問題 – 2012-12-10 23:37:39

+0

這是晚了,但如果你需要它的JavaScript檢查這一個:https://github.com/jkbrzt/rrule – 2016-03-01 10:05:19

回答

0

我意識到這是一個非常古老的問題,但也許這可以幫助其他人有同樣的問題。

首先,我有一點點的類來解析一般的iCalendar數據:

using System.Collections; 

namespace ICalendarHelpers 
{ 
    public class Parser 
    { 
     /// <summary> 
     /// Gets a hashtable representing an entire iCalendar object. 
     /// </summary> 
     /// <param name="data"></param> 
     /// <returns></returns> 
     public static Hashtable Fields(string data) 
     { 
      Hashtable table = new Hashtable(); 

      string[] unfolded = Unfold(data); 

      foreach (string entry in unfolded) 
      { 
       int index = entry.IndexOf(':'); 
       string key = entry.Remove(index); 
       string value = entry.Substring(index + 1); 

       if (!table.ContainsKey(key)) // Avoid duplicate entries 
        table.Add(key, value); 
      } 

      return table; 
     } 

     /// <summary> 
     /// Gets a hashtable representing the value of a field in an iCalendar object. 
     /// </summary> 
     /// <param name="field"></param> 
     /// <returns></returns> 
     public static Hashtable Values(string field) 
     { 
      Hashtable table = new Hashtable(); 

      string[] split = field.Split(';'); 

      foreach (string entry in split) 
      { 
       int index = entry.IndexOf('='); 
       string key = entry.Remove(index); 
       string value = entry.Substring(index + 1); 

       if (!table.ContainsKey(key)) // Avoid duplicate entries 
        table.Add(key, value); 
      } 

      return table; 
     } 

     private static string[] Unfold(string data) 
     { 
      ArrayList split = Split(data, "\r\n"); 
      int size = split.Count; 

      for (int i = 0; i < size; i++) 
      { 
       string each = (string)split[i]; 

       if (each[0] == ' ') 
       { 
        split[i - 1] += each.Substring(1); 
        split.RemoveAt(i); 
        i--; 
        size--; 
       } 
      } 

      return (string[])split.ToArray(typeof(string)); 
     } 

     private static ArrayList Split(string data, string delimiter) 
     { 
      ArrayList list = new ArrayList(); 

      int index = data.IndexOf(delimiter); 

      while (index != -1) 
      { 
       list.Add(data.Remove(index)); 
       data = data.Substring(index + 2); 
       index = data.IndexOf(delimiter); 
      } 

      if (!string.IsNullOrWhiteSpace(data)) 
       list.Add(data); 

      return list; 
     } 
    } 
} 

所以你在復發數據注意到的第一件事是一堆時區的數據:

DTSTART;TZID=America/New_York:20120710T090000 
DTEND;TZID=America/New_York:20120710T093000 

要轉換從Olson時間(「America/New_York」)到Windows時區(「Eastern Standard Time」),我使用以下功能:

private static Dictionary<string, string> windowsOlsonTimes = new Dictionary<string, string>() 
{ 
    { "W. Central Africa Standard Time", "Africa/Bangui" }, 
    { "Egypt Standard Time", "Africa/Cairo" }, 
    { "Morocco Standard Time", "Africa/Casablanca" }, 
    { "South Africa Standard Time", "Africa/Harare" }, 
    { "Greenwich Standard Time", "Africa/Monrovia" }, 
    { "E. Africa Standard Time", "Africa/Nairobi" }, 
    { "Namibia Standard Time", "Africa/Windhoek" }, 
    { "Alaskan Standard Time", "America/Anchorage" }, 
    { "Argentina Standard Time", "America/Argentina/San_Juan" }, 
    { "Paraguay Standard Time", "America/Asuncion" }, 
    { "Bahia Standard Time", "America/Bahia" }, 
    { "SA Pacific Standard Time", "America/Bogota" }, 
    { "Venezuela Standard Time", "America/Caracas" }, 
    { "SA Eastern Standard Time", "America/Cayenne" }, 
    { "Central Standard Time", "America/Chicago" }, 
    { "Mountain Standard Time (Mexico)", "America/Chihuahua" }, 
    { "Central Brazilian Standard Time", "America/Cuiaba" }, 
    { "Mountain Standard Time", "America/Denver" }, 
    { "Greenland Standard Time", "America/Godthab" }, 
    { "Central America Standard Time", "America/Guatemala" }, 
    { "Atlantic Standard Time", "America/Halifax" }, 
    { "US Eastern Standard Time", "America/Indianapolis" }, 
    { "SA Western Standard Time", "America/La_Paz" }, 
    { "Pacific Standard Time", "America/Los_Angeles" }, 
    { "Mexico Standard Time", "America/Mexico_City" }, 
    { "Montevideo Standard Time", "America/Montevideo" }, 
    { "Eastern Standard Time", "America/New_York" }, 
    { "UTC-02", "America/Noronha" }, 
    { "US Mountain Standard Time", "America/Phoenix" }, 
    { "Canada Central Standard Time", "America/Regina" }, 
    { "Pacific Standard Time (Mexico)", "America/Santa_Isabel" }, 
    { "Pacific SA Standard Time", "America/Santiago" }, 
    { "E. South America Standard Time", "America/Sao_Paulo" }, 
    { "Newfoundland Standard Time", "America/St_Johns" }, 
    { "Central Asia Standard Time", "Asia/Almaty" }, 
    { "Jordan Standard Time", "Asia/Amman" }, 
    { "Arabic Standard Time", "Asia/Baghdad" }, 
    { "Azerbaijan Standard Time", "Asia/Baku" }, 
    { "SE Asia Standard Time", "Asia/Bangkok" }, 
    { "Middle East Standard Time", "Asia/Beirut" }, 
    { "India Standard Time", "Asia/Calcutta" }, 
    { "Sri Lanka Standard Time", "Asia/Colombo" }, 
    { "Syria Standard Time", "Asia/Damascus" }, 
    { "Bangladesh Standard Time", "Asia/Dhaka" }, 
    { "Arabian Standard Time", "Asia/Dubai" }, 
    { "North Asia East Standard Time", "Asia/Irkutsk" }, 
    { "Israel Standard Time", "Asia/Jerusalem" }, 
    { "Afghanistan Standard Time", "Asia/Kabul" }, 
    { "Kamchatka Standard Time", "Asia/Kamchatka" }, 
    { "Pakistan Standard Time", "Asia/Karachi" }, 
    { "Nepal Standard Time", "Asia/Katmandu" }, 
    { "North Asia Standard Time", "Asia/Krasnoyarsk" }, 
    { "Arab Standard Time", "Asia/Kuwait" }, 
    { "Magadan Standard Time", "Asia/Magadan" }, 
    { "N. Central Asia Standard Time", "Asia/Novosibirsk" }, 
    { "West Asia Standard Time", "Asia/Oral" }, 
    { "Myanmar Standard Time", "Asia/Rangoon" }, 
    { "Korea Standard Time", "Asia/Seoul" }, 
    { "China Standard Time", "Asia/Shanghai" }, 
    { "Singapore Standard Time", "Asia/Singapore" }, 
    { "Taipei Standard Time", "Asia/Taipei" }, 
    { "Georgian Standard Time", "Asia/Tbilisi" }, 
    { "Iran Standard Time", "Asia/Tehran" }, 
    { "Tokyo Standard Time", "Asia/Tokyo" }, 
    { "Ulaanbaatar Standard Time", "Asia/Ulaanbaatar" }, 
    { "Vladivostok Standard Time", "Asia/Vladivostok" }, 
    { "Yakutsk Standard Time", "Asia/Yakutsk" }, 
    { "Ekaterinburg Standard Time", "Asia/Yekaterinburg" }, 
    { "Armenian Standard Time", "Asia/Yerevan" }, 
    { "Azores Standard Time", "Atlantic/Azores" }, 
    { "Cape Verde Standard Time", "Atlantic/Cape_Verde" }, 
    { "Cen. Australia Standard Time", "Australia/Adelaide" }, 
    { "E. Australia Standard Time", "Australia/Brisbane" }, 
    { "AUS Central Standard Time", "Australia/Darwin" }, 
    { "Tasmania Standard Time", "Australia/Hobart" }, 
    { "W. Australia Standard Time", "Australia/Perth" }, 
    { "AUS Eastern Standard Time", "Australia/Sydney" }, 
    { "UTC", "Etc/GMT" }, 
    { "UTC-11", "Etc/GMT+11" }, 
    { "Dateline Standard Time", "Etc/GMT+12" }, 
    { "UTC+12", "Etc/GMT-12" }, 
    { "W. Europe Standard Time", "Europe/Amsterdam" }, 
    { "GTB Standard Time", "Europe/Athens" }, 
    { "Romance Standard Time", "Europe/Brussels" }, 
    { "Central Europe Standard Time", "Europe/Budapest" }, 
    { "FLE Standard Time", "Europe/Helsinki" }, 
    { "GMT Standard Time", "Europe/London" }, 
    { "E. Europe Standard Time", "Europe/Minsk" }, 
    { "Russian Standard Time", "Europe/Moscow" }, 
    { "Central European Standard Time", "Europe/Sarajevo" }, 
    { "Mauritius Standard Time", "Indian/Mauritius" }, 
    { "Samoa Standard Time", "Pacific/Apia" }, 
    { "New Zealand Standard Time", "Pacific/Auckland" }, 
    { "Fiji Standard Time", "Pacific/Fiji" }, 
    { "Central Pacific Standard Time", "Pacific/Guadalcanal" }, 
    { "West Pacific Standard Time", "Pacific/Guam" }, 
    { "Hawaiian Standard Time", "Pacific/Honolulu" }, 
    { "Tonga Standard Time", "Pacific/Tongatapu" } 
}; 

/// <summary> 
/// Converts a Windows time zone ID to an Olson time zone ID. 
/// </summary> 
/// <param name="tzInfo">A Windows time zone ID.</param> 
/// <returns> 
/// The string corresponding to the Windows time zone ID, 
/// or null if you passed in an invalid Windows time zone ID. 
/// </returns> 
/// <remarks> 
/// See http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/zone_tzid.html 
/// </remarks> 
public static string TimeZoneInfoToOlsonTimeZone(TimeZoneInfo tzInfo) 
{ 
    string olsonTimeZoneId = default(string); 

    if (windowsOlsonTimes.TryGetValue(tzInfo.StandardName, out olsonTimeZoneId)) 
     return olsonTimeZoneId; 

    return null; 
} 

這是使用下面的函數(Appointment是我自己的類和rValue是復發數據):

Appointment appointment = new Appointment(); 
Hashtable fields = Parser.Fields(rValue); 

if (fields.ContainsKey("DTSTART;VALUE=DATE")) 
{ 
    string dtstart = (string)fields["DTSTART;VALUE=DATE"]; 
    string dtend = (string)fields["DTEND;VALUE=DATE"]; 
    appointment.StartDate = SplitDateString(dtstart); 
    appointment.EndDate = SplitDateString(dtend); 
    appointment.AllDay = true; 
} 
else 
{ 
    string tzid = (string)fields["TZID"]; 

    if (fields.ContainsKey("DTSTART;TZID=" + tzid)) 
    { 
     string dtstart = (string)fields["DTSTART;TZID=" + tzid]; 
     string dtend = (string)fields["DTEND;TZID=" + tzid]; 

     string tzoffset = (string)fields[CalendarHelpers.IsDst(DateTime.Now) ? "TZOFFSETTO" : "TZOFFSETFROM"]; 
     TimeSpan offset = SplitTimeString(tzoffset); 

     appointment.StartDate = DateTime.ParseExact(dtstart, "yyyyMMddTHHmmss", CultureInfo.InvariantCulture).Subtract(offset).ToLocalTime(); 
     appointment.EndDate = DateTime.ParseExact(dtend, "yyyyMMddTHHmmss", CultureInfo.InvariantCulture).Subtract(offset).ToLocalTime(); 
    } 
    else 
    { 
     string dtstart = (string)fields["DTSTART"]; 
     string dtend = (string)fields["DTEND"]; 

     if (dtstart.EndsWith("Z")) 
      appointment.StartDate = DateTime.ParseExact(dtstart, "yyyyMMddTHHmmssZ", CultureInfo.InvariantCulture).ToLocalTime(); 
     else 
      appointment.StartDate = DateTime.ParseExact(dtstart, "yyyyMMddTHHmmss", CultureInfo.InvariantCulture); 

     if (dtend.EndsWith("Z")) 
      appointment.EndDate = DateTime.ParseExact(dtend, "yyyyMMddTHHmmssZ", CultureInfo.InvariantCulture).ToLocalTime(); 
     else 
      appointment.EndDate = DateTime.ParseExact(dtend, "yyyyMMddTHHmmss", CultureInfo.InvariantCulture); 
    } 

    appointment.AllDay = false; 
} 

然後我用DDay.iCalhttp://sourceforge.net/projects/dday-ical/)來解析RRULE屬性:

string rrule = (string)fields["RRULE"]; 
RecurrencePattern pattern = new RecurrencePattern(rrule); 

從那裏你只需要弄清楚你想如何在你的應用程序中存儲重複數據,並從RecurrencePattern提供的字段進行轉換。

請注意,我沒有發明一堆上面的代碼,但我很久以前就知道它,我不記得來源。此外,由於我仍在開發我的應用程序,上面的代碼中的一些可能有錯誤。