Parsing 如何在.net中解析包含重复事件的Google日历提要

Parsing 如何在.net中解析包含重复事件的Google日历提要,parsing,google-calendar-api,recurring-events,Parsing,Google Calendar Api,Recurring Events,我需要解析Google日历中的重复事件值。我能够解析除循环对象值之外的其他值。以下是我试图在asp.net MVC(C#)应用程序中从Google日历中提取事件的代码: GOAuthRequestFactory authFactory = new GOAuthRequestFactory("cl", "MyApp"); authFactory.ConsumerKey = ConfigurationManager.AppSettings["GConsumerKey"].ToString(); au

我需要解析Google日历中的重复事件值。我能够解析除循环对象值之外的其他值。以下是我试图在asp.net MVC(C#)应用程序中从Google日历中提取事件的代码:

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

如何解析这个递归元素值?请提出建议。

我意识到这是一个非常古老的问题,但也许这可以帮助其他有同样问题的人

首先,我有一个小类来解析一般的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;
        }
    }
}
要将奥尔森时间(“美国/纽约”)转换为Windows时区(“东部标准时间”),我使用以下功能:

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;
}
然后我使用
DDay.iCal
()解析
RRULE
属性:

string rrule = (string)fields["RRULE"];
RecurrencePattern pattern = new RecurrencePattern(rrule);
从这里,您只需了解如何在应用程序中存储定期数据,以及如何从
RecurrencePattern
提供的字段进行转换


请注意,我并没有发明上面的一堆代码,但我很久以前就得到了它,所以我不记得它的来源。另外,由于我仍在开发我的应用程序,上面的一些代码可能有bug。

我意识到这是一个非常老的问题,但这可能会帮助其他有同样问题的人

首先,我有一个小类来解析一般的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;
        }
    }
}
要将奥尔森时间(“美国/纽约”)转换为Windows时区(“东部标准时间”),我使用以下功能:

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;
}
然后我使用
DDay.iCal
()解析
RRULE
属性:

string rrule = (string)fields["RRULE"];
RecurrencePattern pattern = new RecurrencePattern(rrule);
从这里,您只需了解如何在应用程序中存储定期数据,以及如何从
RecurrencePattern
提供的字段进行转换


请注意,我并没有发明上面的一堆代码,但我很久以前就得到了它,所以我不记得它的来源。另外,由于我仍在开发我的应用程序,上面的一些代码可能有bug。

我在JavaScriptIt's late中有同样的问题,但是如果你需要它来编写javascript,请检查这个问题:我在JavaScriptIt's late中有同样的问题,但是如果你需要它来编写javascript,请检查这个问题: