iCal创建时间偏移

时间:2014-03-06 13:53:23

标签: c# asp.net outlook icalendar

在尝试创建iCal文件时,我遇到了一个我无法追踪的奇怪问题。以下是使用的代码以及设置为从08:00开始并在11:00结束的事件示例。该文件使用相关信息创建,但在尝试将其添加到Outlook时,已将一小时添加到结束时间。

DateTime eventDate = DateTime.Parse("19/06/2014");
DateTime startTime = DateTime.Parse("09:00:00");
DateTime endTime = DateTime.Parse("11:00:00");
string location = "Test Location";
string title = "Test Title";

context.Response.ContentType = "text/x-vcalendar";
string filename = String.Format("attachment; filename={0}.ics", eventname.Replace(" ", "-"));
context.Response.AddHeader("Content-disposition", filename);

context.Response.Write("BEGIN:VCALENDAR" + Environment.NewLine);
context.Response.Write("VERSION:2.0" + Environment.NewLine);
context.Response.Write("METHOD:PUBLISH" + Environment.NewLine);

context.Response.Write("BEGIN:VTIMEZONE" + Environment.NewLine);
context.Response.Write("TZID:Europe/London" + Environment.NewLine);
context.Response.Write("X-LIC-LOCATION:Europe/London" + Environment.NewLine);
context.Response.Write("BEGIN:DAYLIGHT" + Environment.NewLine);
context.Response.Write("TZOFFSETFROM:+0000" + Environment.NewLine);
context.Response.Write("TZOFFSETTO:+0100" + Environment.NewLine);
context.Response.Write("TZNAME:BST" + Environment.NewLine);
context.Response.Write("DTSTART:19700329T010000" + Environment.NewLine);
context.Response.Write("RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU" + Environment.NewLine);
context.Response.Write("END:DAYLIGHT" + Environment.NewLine);
context.Response.Write("BEGIN:STANDARD" + Environment.NewLine);
context.Response.Write("TZOFFSETFROM:+0100" + Environment.NewLine);
context.Response.Write("TZOFFSETTO:+0000" + Environment.NewLine);
context.Response.Write("TZNAME:GMT" + Environment.NewLine);
context.Response.Write("DTSTART:19701025T020000" + Environment.NewLine);
context.Response.Write("RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU" + Environment.NewLine);
context.Response.Write("END:STANDARD" + Environment.NewLine);
context.Response.Write("END:VTIMEZONE" + Environment.NewLine);

context.Response.Write("BEGIN:VEVENT" + Environment.NewLine);
context.Response.Write("ORGANIZER:MAILTO: test@domain.com" + Environment.NewLine);
context.Response.Write("UID: test2@domain.com" + Environment.NewLine);            
context.Response.Write("DTSTART:" + startDate.ToUniversalTime().ToString("yyyyMMddTHHmmssZ") + Environment.NewLine);
context.Response.Write("DTEND:" + GetMeetingEndDate(startDate, endDate).ToString("yyyyMMddTHHmmssZ") + Environment.NewLine);
context.Response.Write("DTSTAMP:" + DateTime.Now.ToUniversalTime().ToString("yyyyMMddTHHmmssZ") + Environment.NewLine);
context.Response.Write("SUMMARY:" + subject + Environment.NewLine);
context.Response.Write("DESCRIPTION:" + description + Environment.NewLine);
context.Response.Write("LAST-MODIFIED:" + DateTime.Now.ToUniversalTime().ToString("yyyyMMddTHHmmssZ") + Environment.NewLine);
context.Response.Write("PRIORITY:5" + Environment.NewLine);
context.Response.Write("LOCATION;ENCODING=QUOTED-PRINTABLE:" + location + Environment.NewLine);
context.Response.Write("CLASS:PUBLIC" + Environment.NewLine);
context.Response.Write("END:VEVENT" + Environment.NewLine);

context.Response.Write("END:VCALENDAR");

此结果是将约会添加到Outlook,开始时间为09:00,结束时间为 12:00 。结束时间增加了一个小时。

请注意,有关的代码仅供英国/ GMT使用。

我已调试此过程并检查所有日期,因为它们已设置且一切正确。我有什么遗漏吗?我真的不想强迫减少结束时间,只是因此它适当地添加到Outlook。

修改

以下是GetMeetingEndDate函数。

DateTime GetMeetingEndDate(DateTime startDate, DateTime endDate)
    {
        DateTime newDate = new DateTime();
        if (endDate < startDate)
        {
            newDate = endDate.AddHours(12);
        }
        else if (endDate == startDate)
        {
            newDate = startDate.AddDays(1).AddHours(-1);
        }
        else
        {
            newDate = endDate;
        }
        return newDate;
    }

谢谢。

1 个答案:

答案 0 :(得分:1)

在下面的代码中: -

context.Response.Write("DTSTART:" + startDate.ToUniversalTime().ToString("yyyyMMddTHHmmssZ") + Environment.NewLine);
context.Response.Write("DTEND:" + GetMeetingEndDate(startDate, endDate).ToString("yyyyMMddTHHmmssZ") + Environment.NewLine);

DTSTART设置为值startDate.ToUniversalTime(),而在函数GetMeetingEndDate中,日期传递而不转换为UTC。因此startdate总是正确的,但iCal会将您的本地enddate视为UTC日期。这可能会导致额外增加小时的问题。解决方案是将以下代码块更改为

context.Response.Write("DTEND:" + GetMeetingEndDate(startDate.ToUniversalTime(), endDate.ToUniversalTime()).ToString("yyyyMMddTHHmmssZ") + Environment.NewLine);