【问题标题】:Set Start and End Time according to time zone for .Ical files?根据.Ical文件的时区设置开始和结束时间?
【发布时间】:2012-04-17 06:06:58
【问题描述】:

我正在使用 C# 代码生成 .ics 文件以将我的事件添加到 Outlook 日历。

.ics 文件使用以下代码生成良好。 但是我这里有一个问题是根据时区设置开始/结束时间。例如,我有 .ics 文件的新加坡标准时间开始/结束时间。我希望如果有人在新加坡打开文件,那么它应该显示新加坡时间,如果有人在印度打开它,那么它应该显示印度时间。就像 2012-04-20 13:00 这次在印度将是上午 10:30 所以如果 .ics 文件在印度打开,.ics 文件将显示 10:30 作为开始时间。

我希望开始和结束时间应该根据系统的时区。那么下面的代码有什么问题,它不起作用。

请帮忙。

代码:

DateTime StartTime = DateTime.Parse("2012-04-20 13:00:00.000Z");//Singapore Standard Time
DateTime EndTime = DateTime.Parse("2012-04-20 14:00:00.000Z");//Singapore Standard Time
bool UseAlarm = true;
                    StringBuilder sb = new StringBuilder(450);
                    sb.Append("BEGIN:VCALENDAR\n");
                    sb.Append("BEGIN:VEVENT\n\n");
                    sb.Append("DTSTART:");
                    sb.Append(StartTime.ToString("yyyyMMdd\\THHmmss\\Z"));
                    sb.Append("\nDTEND:");
                    sb.Append(EndTime.ToString("yyyyMMdd\\THHmmss\\Z"));
                    sb.Append("\nLOCATION:");
                    sb.Append("Location"); 
                    sb.Append("\nCATEGORIES:");
                    sb.Append(string.Empty);
                    sb.Append("\nTRANSP:OPAQUE\n");
                    sb.Append("SEQUENCE:0\n");
                    sb.AppendFormat("UID:RFCALITEM{0}\n", DateTime.Now.Ticks); 
                    sb.Append("DTSTAMP:");
                    sb.Append(StartTime.ToString("yyyyMMdd\\THHmmss\\Z"));
                    sb.Append("\nX-ALT-DESC;FMTTYPE=text/html:");//
                    sb.Append("This is just for testing."); 
                    sb.Append("\nSUMMARY:");
                    sb.Append("Title:Test ICS File"); 
                    sb.Append("\n\nPRIORITY:");
                    sb.Append(5);
                    sb.Append("\nCLASS:PUBLIC\n");
                    if (UseAlarm)
                    {
                        sb.Append("BEGIN:VALARM\n");
                        sb.Append("TRIGGER:PT15M\n");
                        sb.Append("ACTION:DISPLAY\n");
                        sb.Append("DESCRIPTION:Reminder\n");
                        sb.Append("PRIORITY:5\n");
                        sb.Append("END:VALARM\n");
                    }
                    sb.Append("END:VEVENT\n"); 
                    sb.Append("END:VCALENDAR");

【问题讨论】:

    标签: c# icalendar


    【解决方案1】:

    我不想把我的生命押在 Outlook 将如何处理 iCal 数据上,所以这一切都不能保证......但是,您的代码中有一些误解:

    //Singapore Standard Time
    DateTime StartTime = DateTime.Parse("2012-04-20 13:00:00.000Z");
    

    这里的“Z”表示“祖鲁时间”——因此DateTime.Parse 将其解释为 UTC 值,然后将其转换为运行代码的系统上的本地时间。所以在我的机器上,例如(在英国时间,即 2012 年 4 月 20 日的 UTC+1)这将创建一个 DateTime 值,其时间为 14:00。

    如果您希望将值解析为 本地 日期/时间,则不应在此处使用“Z”。

    当您写入该值时,您可以(IIRC - 自从我完成任何 iCal 工作以来已经有一段时间了)表达日期/时间的三种方式之一:

    • 通过包含“Z”作为 UTC 值(正如您当前所做的那样,不正确 - 您将 Z 包含在 local 值的末尾),从而造成混淆事情
    • 作为没有指定时区的一般“本地”日期/时间,例如“无论我身在何处,都在早上 8 点叫醒我”
    • 作为特定时区的日期/时间

    (每种类型的格式详情请咨询RFC 2445。)

    不清楚您想要哪一个 - 第一个可能是最简单的,但您需要使用 UTC 日期/时间,而不是本地日期/时间。

    有一点:.NET 在这里并没有真正帮助您,因为它会将事情与 DateTime 混淆。您不妨考虑使用我的 Noda Time 项目,它将“本地日期/时间”和“特定区域中的日期/时间”分开。

    【讨论】: