Quartz.NET – 这个unit testing不应该通过吗?

这个问题与这个问题有关,但是更加笼统,可以独立对待。

编辑:Quartz版本是v2.0.1

根据我的理解,以下unit testing应通过:

[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); } 

但是(如您所见), nextValidTimeFromBeforenextValidTimeFromBefore不同。 nextValidTimeFromAfter的结果是正确的。 UTC 12:00将在夏季的14:00结束(此时已经开始)。 如果GetNextValidTimeAfter()参数指定夏令时期间或之外的时间,则GetNextValidTimeAfter()

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

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

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

它已在修订版665中修复:

从惊人的安德鲁/大师合并拉出请求#72
CronExpression,日历,CalendarIntervalTriggerImpl的时区问题

包含此修复程序的第一个正式版本是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)); ...