在 DateTime 对象中为 .ics 文件指定时区 - 时间差一个小时(C#、Sitecore 9)
Specifying timezone in DateTime object for .ics file - times are off by an hour (C#, Sitecore 9)
我在 Sitecore 中有每个事件都有开始日期、结束日期和时区,还有一个 link 生成 .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));
public String GetTime(DateTime date, String timezone)
{
var timezoneKey = TimezoneDictionary[timezone];
var tz = TimeZoneInfo.FindSystemTimeZoneById(timezoneKey);
TimeSpan offset = new TimeSpan(0, 0, 0);
if (tz != null)
{
offset = tz.BaseUtcOffset;
}
DateTimeOffset dto = new DateTimeOffset(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, offset);
DateTime utcDate = dto.UtcDateTime;
return utcDate.ToString("yyyyMMddTHHmmssZ");
}
这一切 看起来 都正常工作 - 当我逐步执行它时,我发现 tz
是东部标准时区(我所在的时区),其偏移量为 -5:00。 dto
似乎是 10/21/2019 12:00,偏移量为 -5:00; utcDate.toString("yyyyMMddTHHmmssZ")
给了我 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
returns 在标准时间期间有效的偏移量 - 无论标准时间是否实际有效。在您举办活动时,东部夏令时有效,即 UTC-4 而不是 UTC-5。
不要被 "Eastern Standard Time"
的时区字符串搞糊涂了 - 这确实是正确的 Id
,但它代表 EST 和美东时间。您可以将其视为 "Eastern Time".
要使偏移生效,您可以将代码更改为:
offset = tz.GetUtcOffset(date)
如果您想简化代码,您也可以直接使用 TimeZoneInfo.ConvertTimeToUtc
而不是自己计算偏移量。
我在 Sitecore 中有每个事件都有开始日期、结束日期和时区,还有一个 link 生成 .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));
public String GetTime(DateTime date, String timezone)
{
var timezoneKey = TimezoneDictionary[timezone];
var tz = TimeZoneInfo.FindSystemTimeZoneById(timezoneKey);
TimeSpan offset = new TimeSpan(0, 0, 0);
if (tz != null)
{
offset = tz.BaseUtcOffset;
}
DateTimeOffset dto = new DateTimeOffset(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, offset);
DateTime utcDate = dto.UtcDateTime;
return utcDate.ToString("yyyyMMddTHHmmssZ");
}
这一切 看起来 都正常工作 - 当我逐步执行它时,我发现 tz
是东部标准时区(我所在的时区),其偏移量为 -5:00。 dto
似乎是 10/21/2019 12:00,偏移量为 -5:00; utcDate.toString("yyyyMMddTHHmmssZ")
给了我 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
returns 在标准时间期间有效的偏移量 - 无论标准时间是否实际有效。在您举办活动时,东部夏令时有效,即 UTC-4 而不是 UTC-5。
不要被 "Eastern Standard Time"
的时区字符串搞糊涂了 - 这确实是正确的 Id
,但它代表 EST 和美东时间。您可以将其视为 "Eastern Time".
要使偏移生效,您可以将代码更改为:
offset = tz.GetUtcOffset(date)
如果您想简化代码,您也可以直接使用 TimeZoneInfo.ConvertTimeToUtc
而不是自己计算偏移量。