Quartz.NET - 不应该这个单元测试通过了吗? [英] Quartz.NET - Shouldn't this unit test pass?

查看:195
本文介绍了Quartz.NET - 不应该这个单元测试通过了吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题是这一有关,但保持更一般的,可以独立处理。



编辑:石英版本V2.0.1是



从我的理解,下面的单元测试应该通过:



<预类=郎-CS prettyprint-覆盖> [测试]
公共无效测试(){
//运行的每一个第一天每月14:00
CronExpression表达式=新CronExpression(0 0 14 1 *?);

// TimeZoneInfo.Local = {(UTC + 01:00)阿姆斯特丹,柏林,伯尔尼,罗马,斯德哥尔摩,维也纳}
如果(!TimeZoneInfo.Local.SupportsDaylightSavingTime){
回报;
}

//获取当前时区
VAR daylightChange夏季期间= TimeZone.CurrentTimeZone.GetDaylightChanges(2013年);
// - > daylightChange.Start {2013年3月31日02:00:00} System.DateTime的
// - > daylightChange.End {2013年10月27日03:00:00} System.DateTime的

//得到一个起点前一开始夏季$ B $的B之后的DateTimeOffset beforeSummertime = daylightChange.Start.ToUniversalTime() .AddDays(-1);
的DateTimeOffset afterSummertime = daylightChange.Start.ToUniversalTime()AddDays(1);
// - > beforeSummertime {2013年3月30日01:00:00 +00:00} System.DateTimeOffset
// - > afterSummertime {2013年1月4日01:00:00 +00:00} System.DateTimeOffset

的DateTimeOffset? nextValidTimeFromBefore = expression.GetNextValidTimeAfter(beforeSummertime);
的DateTimeOffset? nextValidTimeFromAfter = expression.GetNextValidTimeAfter(afterSummertime);
// {nextValidTimeFromBefore 13:00:00 2013年4月1日+00:00} System.DateTimeOffset?
// {nextValidTimeFromAfter 12:00:00 2013年4月1日+00:00} System.DateTimeOffset?

Assert.AreEqual(nextValidTimeFromBefore,nextValidTimeFromAfter);
}



但是(正如你所看到的),在 nextValidTimeFromBefore nextValidTimeFromAfter 不同。在 nextValidTimeFromAfter 的结果是正确的。该UTC 12:00将导致夏季14:00时(已在该点开始)。
如果 GetNextValidTimeAfter()参数指定内部或夏季期间以外的时间应该没有问题。



如果NextValidTimes等于或我的做法有缺陷?


解决方案

我想通了,这其实是一个错误Quartz.NET 2.0.1,但它已经被固定在2.1.0。



我查了变化记录网站,该网站并没有提到一个相关的修复。从彼得里奇注释鼓励我再看看较新版本的石英。当我通过我注意到有资料库的提交看起来确实是这个修复



据已被固定在修订版665:




合并拉请求,#72,从惊人的安德鲁/带CronExpression,日历,CalendarIntervalTriggerImpl


中间结果
时区的问题< /块引用>

这包含此修复程序的第一个正式发布V2.1.0,这是在标签的修订685。



错误是位于 CronExpression.GetTimeAfter()(这是由 CronExpression.GetNextValidTimeAfter(叫)):

  ... 
D =新的DateTimeOffset(年,d.Month,d.Day,d.Hour,d.Minute, d.Second,d.Offset);

//应用适当此日期偏移量(这是不存在)
D =新的DateTimeOffset(d.Year,d.Month,d.Day,d.Hour,D。分钟,d.Second,this.TimeZone.GetUtcOffset(d.DateTime));
...


This question is related to this one, but is kept more general and can be treated independently.

EDIT: Quartz version is v2.0.1

From my understanding, the following unit test should pass:

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

However (as you can see), the nextValidTimeFromBefore differs from nextValidTimeFromAfter. The result in nextValidTimeFromAfter is correct. The UTC 12:00 will result in 14:00 during summertime (which already started at that point). It shouldn't matter if the GetNextValidTimeAfter() parameter specifies a time inside or outside of the summertime period.

Should the NextValidTimes be equal or is my approach flawed?

解决方案

I figured out that this actually is a bug in Quartz.NET 2.0.1, but it has already been fixed in 2.1.0.

I checked the change-log on the site, which does not mention a related fix. The comment from Peter Ritchie encouraged me to take another look at the newer Quartz versions. When i looked through the commits in the repository i noticed there actually was a fix for this.

It has been fixed in revision 665:

Merge pull request #72 from amazing-andrew/master
Time zone issues with CronExpression, calendars, CalendarIntervalTriggerImpl

The first official release that contains this fix is v2.1.0, which was tagged at revision 685.

The bug was located in CronExpression.GetTimeAfter() (which is called by 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));
...

这篇关于Quartz.NET - 不应该这个单元测试通过了吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆