【问题标题】:Recurring events lose automatic timezone conversion重复事件丢失自动时区转换
【发布时间】:2018-07-15 21:37:53
【问题描述】:

我正在使用 ical.net 设置日历邀请电子邮件。发送非重复事件似乎很有效:我这样设置开始和结束日期

iCalEvent.DtStart = new CalDateTime(DateTime.SpecifyKind(model.EventTime.Value, DateTimeKind.Utc));
iCalEvent.DtEnd = new CalDateTime(DateTime.SpecifyKind(model.EventTime.Value.AddMinutes(model.DurationMins.Value), DateTimeKind.Utc));

邮件到达时,时区已转换为收件人时区(时区为-7,事件时间为下午4点,持续时间为3小时)

但是,当我采用完全相同的代码并将这一行添加到其中时

IRecurrencePattern recurrence = new RecurrencePattern(FrequencyType.Daily, 1)
{
    Until = DateTime.SpecifyKind(model.endDate.Value.AddDays(1), DateTimeKind.Utc)
};

iCalEvent.RecurrenceRules = new List<IRecurrencePattern> { recurrence };

突然收到邮件时我的时区不再转换(时区为-7,事件时间为下午4点,持续时间为3小时。结束日期为28号)

我需要在用户自己的时区向用户显示 DateTime,并且我需要显示从 eventTime 到 endDate 的重复事件

注意我没有在日历上指定时区属性也可能很有用,因为它导致发送的电子邮件在 Outlook 中显示“不支持的日历消息”。在我删除它之前,它看起来像这样

iCal.AddTimeZone(new VTimeZone("UTC"));

当我打开指定了这个时区的 ical 文件时,它们似乎在多天的事件中正常工作,但由于我需要它们在 Outlook 中出现并带有接受/拒绝/暂定按钮,所以不可能加回来

我也尝试过像这样指定日期时间

iCalEvent.DtStart = new CalDateTime(leEvent.EventTime.Value, "UTC");

但没有任何改变

编辑:我现在知道问题是由于需要指定时区的重复事件here,但我不太确定需要在哪里指定时区。我回去重新添加 vTimeZone 并通过this 站点对其进行验证,似乎 iCal 文件缺少时区块内的标准/日光部分

我还尝试将时区指定为 GMT 并将时区指定为 "\"America/Phoenix\"" 以便 tzid 以 TZID:"America/Phoenix" 的形式出现(在 ical 文件中带有引号。

这是我目前导致问题的代码。

iCalEvent.DtStart = new CalDateTime(DateTime.SpecifyKind(model.EventTime.Value, DateTimeKind.Utc));
iCalEvent.DtEnd = new CalDateTime(iCalEvent.DtStart.Value.AddMinutes(model.DurationMins.Value));

if (model.EndDate.HasValue)
{
    IRecurrencePattern recurrence = new RecurrencePattern(FrequencyType.Daily, 1)
    {
        Until = DateTime.SpecifyKind(model.MaxDate.Value, DateTimeKind.Utc).ToLocalTime()
    };

    iCalEvent.RecurrenceRules = new List<IRecurrencePattern> { recurrence };

    iCalEvent.DtStart = new CalDateTime(iCalEvent.DtStart.Value.ToLocalTime(), "America/Phoenix");
    iCalEvent.DtEnd = new CalDateTime(iCalEvent.DtEnd.Value.ToLocalTime(), "America/Phoenix");
    iCal.AddTimeZone(new VTimeZone("America/Phoenix"));
}

我不太确定从这一点开始纠正标准/日光错误需要发生什么。

最终编辑:

看完this的帖子,我发现这个问题在去年11月就已经解决了。我检查了我们项目中的版本,结果发现一些天才只是直接复制了 dll,而没有通过 nuget 设置它(以及几年前的版本)。我抓住了最新版本,这次指定时区在 Outlook 中没有引起任何问题。我仍在试验 addTimeZone 和 addLocalTimeZone 但我绝对走在正确的轨道上。感谢 rianjs 提供了这个非常有用的库。如果没有它,我不知道如何使用这个疯狂的日历标准。

【问题讨论】:

    标签: c# outlook icalendar ical-dotnet


    【解决方案1】:

    重复性事件始终与发送者的时区(或者更确切地说与事件位置)相关,而不是与接收者的时区相关,因为组织者和各个接收者之间可能会在不同时间发生夏令时变化。

    因此,在大多数情况下,您希望在事件中使用有意义的时区(即不是 UTC)。 然后 Outlook 只是显示事件确实根据给定的时区发生。这表明对于收件人而言,该事件可能并不总是在一天中的同一时间进行。

    【讨论】:

    • 感谢您的帮助,因为这是朝着正确方向迈出的一步,尽管我仍在尝试找出实现细节。我更新了我的问题以反映我已根据此建议采取的步骤
    • 将此标记为正确答案,因为这是我在最初的帖子中遗漏的细节。我再次更新了帖子,进一步详细说明了我的过程以及我最终做了什么。
    【解决方案2】:

    由于我花了这么长时间才弄清楚,我不妨分享我的解决方案,以防其他人遇到这个问题并发现这个问题。

    我用两个具有良好 utc 的日期时间定义了 DtStart/DtEnd

    calendarEvent.DtStart = new CalDateTime(model.EventTime.Value);
    calendarEvent.DtEnd = new CalDateTime(model.EventTime.Value.AddMinutes(model.DurationMins.Value));
    

    这对于单日活动非常有效,但在多日活动中我最终这样做了

    if (model.EndDate.HasValue)
    {
        RecurrencePattern recurrence = new RecurrencePattern(FrequencyType.Daily, 1)
        {
            Until = model.EndDate.Value //has kind: Utc
        };
    
        var timezoneOffsetString = "Etc/GMT";
        if (timezoneOffset > 0) //client time zone offset, calculated through js
        {
            timezoneOffsetString += "-" + timezoneOffset;
        }
        else if (timezoneOffset < 0)
        {
            timezoneOffsetString += "+" + (-1 * timezoneOffset);
        }
    
        calendar.AddTimeZone(timezoneOffsetString);
        calendarEvent.DtStart = calendarEvent.DtStart.ToTimeZone(timezoneOffsetString);
        calendarEvent.DtEnd = calendarEvent.DtEnd.ToTimeZone(timezoneOffsetString);
    
        calendarEvent.RecurrenceRules = new List<RecurrencePattern> { recurrence };
    }
    

    这不是完全证明,因为有些地方可能有奇怪的 dst 问题,但 nodatime 将“美国/凤凰” tzid 视为 LMT 时间,这给了我 28 分钟的时间......此外,处理所有GMT 日期更接近我们在应用程序其余部分中的实施,因此它适用于我的情况

    This solution 让我想到了将 Etc/GMT 的东西拼凑起来。

    【讨论】:

      猜你喜欢
      • 2013-08-09
      • 2011-10-27
      • 2017-02-27
      • 2011-09-17
      • 1970-01-01
      • 2018-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多