How do I control the TimeZone of events returned by the .NET Google Calendar API?
I have the following code for use in my asp.net website:
CalendarService service = new CalendarService("mycalendar");
EventQuery query = new EventQuery();
query.Uri = new Uri(group.GroupEventsURL);
query.Si开发者_如何学JAVAngleEvents = true;
query.SortOrder = CalendarSortOrder.ascending;
query.ExtraParameters = "orderby=starttime";
query.NumberToRetrieve = 50;
query.TimeZone = "America/Chicago";
EventFeed feed = service.Query(query);
Which produces the following URL:
http://www.google.com/calendar/feeds/TRIMMEDgroup.calendar.google.com/private-TRIMMED/full?max-results=50&orderby=starttime&ctz=America%2FChicago&sortorder=ascending&singleevents=true
According to the documentation (emphasis mine), I expect the Times in each EventEntry to be in the Central time zone:
ctz: The current timezone. If not specified, times are returned in the calendar time zone.
- Times in the resulting feed will be represented in this timezone.
- Replace all spaces with underscores (e.g. "ctz=America/Los_Angeles").
But my server is hosted in Arizona, so (for now) all of the dates on the calendar are two hours earlier than they should be. Am I doing something wrong? How do I get the dates in the feed to be in the Central time zone even though the server is in Arizona?
I do not plan on moving my hosting any time soon, but since Arizona does not participate in Daylight Savings Time, I cannot simply add two hours to every date.
Don't fight it. The Google.GData.Calendar library sets each time to the system's local time. Here's what I could dig up about it.
You'll need to convert all those times from every EventEntry
DateTime offsetStartTime = GetTimeZoneOffset(entry.Times[0].StartTime, "Mountain Standard Time");
public static DateTime GetTimeZoneOffset(DateTime dt, string win32Id)
{
var timeUtc = dt.ToUniversalTime();
TimeZoneInfo cstZone = TimeZoneInfo.FindSystemTimeZoneById(win32Id);
DateTime cstTime = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, cstZone);
return cstTime;
}
I am still open to other ideas, but here is what I got to work. I created my own CalendarService
class, which converts the dates from:
2010-10-13T18:30:00.000-05:00
to:
2010-10-13 18:30:00
These dates are then converted to the same (and correct) DateTime in any time zone.
internal class CalendarService2 : CalendarService
{
public CalendarService2(string applicationName) : base(applicationName) { }
public new EventFeed Query(EventQuery feedQuery)
{
EventFeed feed = new EventFeed(feedQuery.Uri, this);
using (Stream input = base.Query(feedQuery.Uri, DateTime.MinValue))
{
XmlDocument doc = new XmlDocument();
doc.Load(input);
XmlNodeList nodes = doc.SelectNodes("(//@startTime|//@endTime)[contains(.,'.000-')]");
foreach (XmlNode node in nodes)
{
node.Value = node.Value.Remove(node.Value.Length - 10).Replace('T', ' ');
}
using (MemoryStream output = new MemoryStream())
{
doc.Save(output);
output.Position = 0;
feed.NewAtomEntry += new FeedParserEventHandler(this.OnParsedNewEntry);
feed.NewExtensionElement += new ExtensionElementEventHandler(this.OnNewExtensionElement);
feed.Parse(output, AlternativeFormat.Atom);
}
}
return feed;
}
}
精彩评论