【问题标题】:Quartz.NET - Shouldn't this unit test pass?Quartz.NET - 这个单元测试不应该通过吗?
【发布时间】:2013-03-18 22:14:17
【问题描述】:

这个问题与this one有关,但保持更笼统,可以独立处理。

编辑: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);
}  

但是(如您所见),nextValidTimeFromBeforenextValidTimeFromAfter 不同。 nextValidTimeFromAfter 中的结果是正确的。 UTC 12:00 将导致夏令时 14:00(此时已经开始)。 GetNextValidTimeAfter() 参数指定的时间是在夏季时间段之内还是之外都无关紧要。

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

【问题讨论】:

  • 这对我来说很好(我不在你的 TZ 中),如果我只是创建一个新的 DaylightTime 对象,其中包含你详细说明的开始和结束日期(例如 daylightChange = new DaylightTime(new DateTime(2013, 3, 31, 2, 0, 0), new DateTime(2013, 10, 27, 2, 0, 0), TimeSpan.MinValue))它也通过了。
  • 谢谢,这鼓励我再看一下较新的 Quartz 版本。我已经检查了网站上的更改日志,其中没有提到相关的修复。但是,当我查看存储库中的提交时,我注意到实际上有一个解决方法。我将添加一个包含详细信息的答案。
  • 我用 2.1.2.400, FWIW 试过这个

标签: c# unit-testing timezone quartz.net dst


【解决方案1】:

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

我检查了网站上的更改日志,其中没有提到相关的修复。 Peter Ritchie 的评论鼓励我重新审视 Quartz 的新版本。当我查看存储库中的提交时,我注意到实际上有一个解决方法。

已在修订版 665 中修复:

合并来自 Amazing-andrew/master 的拉取请求 #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));
...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-02
    • 2023-03-19
    • 2012-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-16
    相关资源
    最近更新 更多