Quartz.NET - 使用/了解基于cron的触发器和时区/夏令时(夏令时)

时间:2013-03-27 14:22:39

标签: c# timezone quartz-scheduler quartz.net

为了举例,我们使用以下cron表达式:“0 0 14 1 *?”
- >每个月的第一天14:00开火。

我使用Quartz CronScheduleBuilder来构建探索,但这无关紧要。

我的当地时区是UTC + 01:00,夏季(今年)从2013年3月31日2:00开始,时间调整为3:00。

当我使用建议的触发器安排一个新的Job时,比如20.02.2013,Quartz正确计算出“NextFireTimeUtc”的System.DateTimeOffset: DateTime:01.03.2013 13:00:00(这是UTC时间,比当地时区晚一个小时)
LocalDateTime:01.03.2013 14:00:00

作业将在指定的14:00时正确触发。

现在,如果我在20.03.2013安排工作,“NextFireTimeUtc”会导致:
DateTime:01.04.2013 13:00:00(这是UTC时间,现在比当地时区晚两个小时)
LocalDateTime:01.04.2013 15:00:00

请注意,生成的NextFireTimeUtc现在属于本地夏令时。结果,LocalDateTime也被“校正”了UTC一小时。这导致作业在15:00运行,这不是我想要的。

我(显然)期望的是cron表达式中的“14”应该总是导致触发器在14:00触发,即使在夏季也是如此。

必须有一种简单的方法来处理这种现象,我可能只是遗漏了一些概念。我很困惑。

修改
问题似乎是,Quartz根据当前时区信息计算第一 NextFireTimeUtc。为了测试这个,我安排了两个不同的cron触发器,并在触发器上调用了GetFireTimeAfter(),增加了偏移量,以查看一年中产生的火灾时间。

触发1:每月28日14点开火

  

GetFireTimeAfter now + 00 months:28.03.2013 13:00:00 +00:00 < - 这是正确的

  GetFireTimeAfter now + 01 months:28.04.2013 12:00:00 +00:00
  GetFireTimeAfter now + 02 months:28.05.2013 12:00:00 +00:00
  GetFireTimeAfter now + 03 months:28.06.2013 12:00:00 +00:00
  GetFireTimeAfter now + 04 months:28.07.2013 12:00:00 +00:00
  GetFireTimeAfter now + 05 months:28.08.2013 12:00:00 +00:00
  GetFireTimeAfter now + 06 months:28.09.2013 12:00:00 +00:00
  GetFireTimeAfter now + 07 months:28.10.2013 13:00:00 +00:00< - 夏季已经结束
  GetFireTimeAfter now + 08 months:28.11.2013 13:00:00 +00:00

第一次开火时间是正确的,因为它仍然属于“冬季”。 “夏令时”的时间减去额外的-1,导致当地时区增加+2后正确的开火时间。

触发器1:每个月的第一天14:00开火

  

GetFireTimeAfter now + 00 months:01.04.2013 13:00:00 +00:00 < - 这是错的?
  GetFireTimeAfter now + 01 months:01.05.2013 12:00:00 +00:00
  GetFireTimeAfter now + 02 months:01.06.2013 12:00:00 +00:00
  GetFireTimeAfter now + 03 months:01.07.2013 12:00:00 +00:00
  GetFireTimeAfter now + 04 months:01.08.2013 12:00:00 +00:00
  GetFireTimeAfter now + 05 months:01.09.2013 12:00:00 +00:00
  GetFireTimeAfter now + 06 months:01.10.2013 12:00:00 +00:00
  GetFireTimeAfter now + 07 months:01.11.2013 13:00:00 +00:00< - 夏季已经结束
  GetFireTimeAfter now + 08 months:01.12.2013 13:00:00 +00:00

第一次火灾已经在夏季,但它仅偏移-1,导致本地触发时间为15:00。

所以触发器很好,除了第一个触发时间,如果它在冬季安排并且第一次执行落在夏季。如何处理?

1 个答案:

答案 0 :(得分:2)

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

有关详细信息,请参阅this answer