Quartz.NET - 这个单元测试不应该通过吗?

Rev*_*1.0 5 c# timezone unit-testing dst quartz.net

这个问题关系到这一个,但一直比较一般,可以独立处理.

编辑:Quartz版本是v2.0.1

根据我的理解,以下单元测试应通过:

[Test]
public void Test() {
    // run every first day of month at 14:00 hours
    CronExpression expression = new CronExpression("0 0 14 1 * ?");

    //  TimeZoneInfo.Local = {(UTC+01:00) Amsterdam, Berlin, Bern, Rom, Stockholm, Wien}
    if (!TimeZoneInfo.Local.SupportsDaylightSavingTime) {
        return;
    }

    // get "summertime" period for current timezone
    var daylightChange = TimeZone.CurrentTimeZone.GetDaylightChanges(2013);
    //  -> daylightChange.Start     {31.03.2013 02:00:00}   System.DateTime
    //  -> daylightChange.End       {27.10.2013 03:00:00}   System.DateTime

    // get one startpoint before and one after begin of summertime
    DateTimeOffset beforeSummertime = daylightChange.Start.ToUniversalTime().AddDays(-1);
    DateTimeOffset afterSummertime = daylightChange.Start.ToUniversalTime().AddDays(1);
    // -> beforeSummertime  {30.03.2013 01:00:00 +00:00}    System.DateTimeOffset
    // -> afterSummertime   {01.04.2013 01:00:00 +00:00}    System.DateTimeOffset

    DateTimeOffset? nextValidTimeFromBefore = expression.GetNextValidTimeAfter(beforeSummertime);
    DateTimeOffset? nextValidTimeFromAfter = expression.GetNextValidTimeAfter(afterSummertime);
    // nextValidTimeFromBefore  {01.04.2013 13:00:00 +00:00}    System.DateTimeOffset?
    // nextValidTimeFromAfter   {01.04.2013 12:00:00 +00:00}    System.DateTimeOffset?

    Assert.AreEqual(nextValidTimeFromBefore, nextValidTimeFromAfter);
}  
Run Code Online (Sandbox Code Playgroud)

然而(正如你所看到的),nextValidTimeFromBefore不同于nextValidTimeFromAfter.结果nextValidTimeFromAfter是正确的.UTC 12:00将在夏季的14:00结束(此时已经开始).如果GetNextValidTimeAfter()参数指定夏季时段内部或外部的时间,则无关紧要.

NextValidTimes应该相等还是我的方法有缺陷?

Rev*_*1.0 8

我发现这实际上是Quartz.NET 2.0.1中的一个错误,但它已经在2.1.0中得到修复.

我检查了网站上的更改日志,但未提及相关修复.Peter Ritchie的评论鼓励我再看看更新的Quartz版本.当我查看存储库中的提交时,我注意到实际上有一个修复程序.

它已在修订版665中修复:


使用CronExpression,日历,CalendarIntervalTriggerImpl 从惊人的andrew/master 时区问题合并拉取请求#72

包含此修复程序的第一个正式版本是v2.1.0,它在版本685处标记.

该错误位于CronExpression.GetTimeAfter()(被称为CronExpression.GetNextValidTimeAfter()):

...
d = new DateTimeOffset(year, d.Month, d.Day, d.Hour, d.Minute, d.Second, d.Offset);

// apply the proper offset for this date (this wasn't there)
d = new DateTimeOffset(d.Year, d.Month, d.Day, d.Hour, d.Minute, d.Second, this.TimeZone.GetUtcOffset(d.DateTime));
...
Run Code Online (Sandbox Code Playgroud)