在.ics文件的DateTime对象中指定时区-时间缩短一小时(C#,Sitecore 9)

在.ics文件的DateTime对象中指定时区-时间缩短一小时(C#,Sitecore 9),c#,datetime,timezone,utc,timezone-offset,C#,Datetime,Timezone,Utc,Timezone Offset,我在Sitecore中有一些事件,每个事件都有一个开始日期、结束日期和时区,还有一个生成.ics文件的链接,用于将这些事件添加到您的日历中(例如Outlook)。最初,时间相差甚远,因为(我认为)Sitecore中存储的时间是UTC,所以尽管页面上显示为12:00-3:00,因为该时间是UTC,日历事件将显示为5:00-8:00 这是原始代码: StringBuilder sb = new StringBuilder(); sb.AppendLine("BEGIN:VCALENDAR"); sb

我在Sitecore中有一些事件,每个事件都有一个开始日期、结束日期和时区,还有一个生成.ics文件的链接,用于将这些事件添加到您的日历中(例如Outlook)。最初,时间相差甚远,因为(我认为)Sitecore中存储的时间是UTC,所以尽管页面上显示为12:00-3:00,因为该时间是UTC,日历事件将显示为5:00-8:00

这是原始代码:

StringBuilder sb = new StringBuilder();
sb.AppendLine("BEGIN:VCALENDAR");
sb.AppendLine("VERSION:2.0");
sb.AppendLine("PRODID:-//IFT.org//NONSGML Events//EN");
sb.AppendLine("BEGIN:VEVENT");
sb.AppendFormat("DTSTART;VALUE DATE-TIME:{0}\n", eventDates.Start_Date.ToUniversalTime().ToString("yyyyMMddTHHmmssZ"));
sb.AppendFormat("DTEND;VALUE DATE-TIME:{0}\n", eventDates.End_Date.ToUniversalTime().ToString("yyyyMMddTHHmmssZ"));
我在指定的时区中添加了以下代码:

var timezone = eventDates.Time_Zone?._Name;
sb.AppendFormat("DTSTART;VALUE DATE-TIME:{0}\n", GetTime(eventDates.Start_Date, timezone));
sb.AppendFormat("DTEND;VALUE DATE-TIME:{0}\n", GetTime(eventDates.End_Date, timezone));

这一切看起来都是正确的-当我一步一步地通过它时,我得到
tz
是东部标准时区(我所在的时区),偏移量为-5:00<代码>dto显示为2019年10月21日12:00,偏移量为-5:00
utcDate.toString(“yyyymmddthhmmsz”)
给了我看起来正确的
20191023T170000Z
(因为12:00+5:00=17:00)。但是,当我打开.ics文件时,时间显示为1:00和4:00,而不是12:00和3:00(时区表示东部时间)

我不确定这是我的代码还是Outlook的问题,但这是我的.ics文件:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//IFT.org//NONSGML Events//EN
BEGIN:VEVENT
DTSTART;VALUE DATE-TIME:20191023T170000Z
DTEND;VALUE DATE-TIME:20191026T000000Z
SUMMARY:summary
DESCRIPTION:description
LOCATION:Sun Valley, Idaho
URL;VALUE=URI:http://mysite/events/event-listing/2019/oct/symposium
UID:f10b3138-2737-46d6-b1c0-cbdc18cc0ef6
END:VEVENT
END:VCALENDAR

tz.BaseUtcOffset
返回在标准时间内有效的偏移量-无论标准时间是否实际有效。在您举办活动时,东部夏令时生效,即UTC-4而非UTC-5

不要被时区字符串
“东部标准时间”
所迷惑-这确实是
Id
的正确用法,但它同时表示EST和EDT。你可以把它想象成“东部时间”

要使偏移生效,可以将代码更改为:

offset = tz.GetUtcOffset(date)

如果你想简化你的代码,你也可以只使用
TimeZoneInfo.ConvertTimeToUtc
而不是自己计算偏移量。

哦,还有一件事-如果你的事件时间可能接近DST转换(当我们从EST切换到EDT或返回时),然后,您应该考虑如何处理不明确和无效的本地时间。一种方法是使用
ToDateTimeOffset
扩展方法,然后像在原始代码中一样获取结果的
.UtcDateTime
属性。
offset = tz.GetUtcOffset(date)