我需要解析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
我如何解析此Recurrence元素值?请建议。
答案 0 :(得分: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时区(“东部标准时间”),我使用以下功能:
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.iCal
(http://sourceforge.net/projects/dday-ical/)来解析RRULE
属性:
string rrule = (string)fields["RRULE"];
RecurrencePattern pattern = new RecurrencePattern(rrule);
从那里,您只需要弄清楚如何在应用程序中存储重复数据,并从RecurrencePattern
提供的字段进行转换。
请注意,我没有发明一堆上面的代码,但是很久以前我就知道了我不记得这些代码。此外,由于我仍在开发我的应用程序,上面的一些代码可能有错误。