【问题标题】:Does DDay Ical library calculate recurring rules correctly?DDay Ical 库是否正确计算重复规则?
【发布时间】:2016-10-27 19:09:46
【问题描述】:

我已经进行了一些测试。这是我的代码:

var systemTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
var icalTimeZone = iCalTimeZone.FromSystemTimeZone(systemTimeZone);

var startTimeSearch = new DateTime(2015, 9, 8, 0, 0, 0, DateTimeKind.Utc);
var endTimeSearch = new DateTime(2015, 12, 1, 00, 0, 0, DateTimeKind.Utc);

var iCalendar = new iCalendar();
var pacificTimeZone = _iCalendar.AddTimeZone(icalTimeZone);

var event = new Event
{
    Summary = "This is an event at 2015-09-08 10:30 PST (2015-09-08 17:30 UTC)",
    DTStart = new iCalDateTime(2015, 9, 8, 10, 30, 0, pacificTimeZone.TZID, iCalendar),
    Duration = new TimeSpan(0, 1, 0, 0)
};

var rp = new RecurrencePattern("FREQ=WEEKLY;UNTIL=20151112T080000Z;WKST=SU;BYDAY=TU");

event.RecurrenceRules.Add(rp);
iCalendar.Events.Add(_event);
var occurrences = iCalendar.GetOccurrences(startTimeSearch, endTimeSearch);

结果如下:

10 次出现 - 这是出现的 Period.StartTime.Value 和 UTC 属性

价值 - 2015 年 9 月 8 日 10:30:00 - UTC 2015 年 9 月 8 日 17:30:00
价值强> - 2015 年 9 月 15 日 10:30:00 - UTC 2015 年 9 月 15 日 17:30:00
- 2015 年 9 月 22 日 10 :30:00 - UTC 2015 年 9 月 22 日 17:30:00
- 2015 年 9 月 29 日 10:30:00 - UTC 2015 年 9 月 29 日 17:30:00
价值 - 2015 年 10 月 6 日 10:30:00 - UTC 2015 年 10 月 6 日17:30:00
- 10/13/2015 10:30:00 - UTC 10/13/2015 17:30:00
价值
- 10/20/2015 10:30:00 - UTC 10/20/2015 17:30:00
价值 - 10 /27/2015 10:30:00 - UTC 10/27/2015 17:30:00
-11/3/2015 10:30:00 - UTC 2015 年 11 月 3 日 17:30:00 (应该是 18:30:00!)
- 11 /10/2015 10:30:00 - UTC 11/10/2015 17:30:00 (应该是 18:30:00!)

如您所见,最后两个的 UTC 时间应为 18:30:00。所以我想知道这是否正是 DDay Ical 的工作方式,我不应该指望它正确地获得 UTC 日期时间,或者我做错了什么。

【问题讨论】:

  • 会不会和夏令时有关?

标签: c# icalendar recurring-events dday


【解决方案1】:

由于夏令时,您会得到这个时差。一种可能的解决方案是不按名称获取时区Pacific Standard Time

 // First load a file containing time zone information for Pacific Standard Time
var systemTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");

代替这个使用系统时区

var systemTimeZone = TimeZoneInfo.GetSystemTimeZones().FirstOrDefault();

或者简单地添加本地时区:

iCalendar iCalendar= new iCalendar();
iCalendar.AddLocalTimeZone();

要查找所有注册的时区,click here

ReadOnlyCollection<TimeZoneInfo> zones = TimeZoneInfo.GetSystemTimeZones();
Console.WriteLine("The local system has the following {0} time zones", zones.Count);
foreach (TimeZoneInfo zone in zones)
   Console.WriteLine(zone.Id);

我只是在我的代码中使用GetSystemTimeZones()

public static void Test1()
    {
        var systemTimeZone = TimeZoneInfo.GetSystemTimeZones().FirstOrDefault();
        //TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
        var icalTimeZone = iCalTimeZone.FromSystemTimeZone(systemTimeZone);

        var startTimeSearch = new DateTime(2015, 9, 8, 0, 0, 0, DateTimeKind.Utc);
        var endTimeSearch = new DateTime(2015, 12, 1, 00, 0, 0, DateTimeKind.Utc);

        var iCalendar = new iCalendar();
        var pacificTimeZone = iCalendar.AddTimeZone(icalTimeZone);

        var _event =
        new Event
        {
            Summary = "This is an event at 2015-09-08 10:30 PST (2015-09-08 17:30 UTC)",
            DTStart = new iCalDateTime(2015, 9, 8, 10, 30, 0, pacificTimeZone.TZID, iCalendar),
            Duration = new TimeSpan(0, 1, 0, 0)
        };

        var rp = new RecurrencePattern("FREQ=WEEKLY;UNTIL=20151112T080000Z;WKST=SU;BYDAY=TU");

        _event.RecurrenceRules.Add(rp);
        iCalendar.Events.Add(_event);

        var occurrences = iCalendar.GetOccurrences(startTimeSearch, endTimeSearch);
    }

当我调试它得到输出像

您可以相应地更改时区并获得结果。希望对你有帮助。

【讨论】:

  • 谢谢。我知道夏令时的问题。正如我的问题所示,我得到了正确的 PST 值 - 这是不正确的 UTC。我看不出你的回答如何解决我的问题。
  • 好的,所以答案是否定的,DDay Ical 不能正确计算出现次数。对吗?
  • 我不认为这是一个错误或错误。这就是 DDay 的设计方式。如果您牢记夏令时,则发生的情况是正确的。
【解决方案2】:

Don't use dday.ical;使用ical.net

这应该让你开始:

var iCalendar = new Calendar();

var start = new DateTime(2015, 9, 8, 10, 30, 0);
var e = new Event
{
    Summary = "This is an event at 2015-09-08 10:30 PST (2015-09-08 17:30 UTC)",
    DtStart = new CalDateTime(start, "Pacific Standard Time"),
    Duration = TimeSpan.FromHours(1)
};

var rp = new RecurrencePattern("FREQ=WEEKLY;UNTIL=20151112T080000Z;WKST=SU;BYDAY=TU");
e.RecurrenceRules.Add(rp);
iCalendar.Events.Add(e);

var startTimeSearch = new DateTime(2015, 9, 8, 0, 0, 0, DateTimeKind.Utc);
var endTimeSearch = new DateTime(2015, 12, 1, 00, 0, 0, DateTimeKind.Utc);
var occurrences = iCalendar.GetOccurrences(startTimeSearch, endTimeSearch);

结果:

【讨论】:

    【解决方案3】:

    我可以解决这个问题。原来你不应该在ExceptionDates中指定时间,只需要添加date组件,

    这似乎有效,GetOccurances 现在可以正确识别异常日期。希望这能帮助经历同样痛苦的人。

    【讨论】:

      猜你喜欢
      • 2015-05-18
      • 1970-01-01
      • 2016-10-27
      • 1970-01-01
      • 2017-12-04
      • 2011-12-06
      • 2014-03-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多