Указание часового пояса в объекте DateTime для файла .ics - время отключено на час (C #, Sitecore 9) - PullRequest
1 голос
/ 21 октября 2019

У меня есть события в 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));

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: 21.10.2009, 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

1 Ответ

2 голосов
/ 22 октября 2019

tz.BaseUtcOffset возвращает смещение, которое действует в течение стандартного времени - независимо от того, действует ли стандартное время на самом деле или нет. На время вашего мероприятия действует восточное летнее время, то есть UTC-4, а не UTC-5.

Не следует путать строку часового пояса "Eastern Standard Time" - это действительноисправьте Id, но оно представляет и EST и EDT. Вы можете думать об этом как о «восточном времени».

Чтобы получить смещение, вы можете изменить свой код на:

offset = tz.GetUtcOffset(date)

Если вы хотите упростить свой код, выможно также использовать TimeZoneInfo.ConvertTimeToUtc вместо того, чтобы вычислять смещение самостоятельно.

...