石英.使用/理解基于cron的触发器和时区/夏令时(夏令时)

本文关键字:夏令时 触发器 时区 cron 使用 石英 | 更新日期: 2023-09-27 18:06:21

让我们使用下面的cron表达式:"0 0 14 1 * ?"
->每月1日14:00时开火。

我使用石英CronScheduleBuilder来构建表达式,但这是无关的。

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

当我使用提议的触发器在2013年2月20日调度一个新作业时,Quartz计算系统。"NextFireTimeUtc"的DateTimeOffset正确为:
DateTime: 01.03.2013 13:00:00(这是UTC时间,比当地时区晚一个小时)
LocalDateTime: 01.03.2013 14:00:00

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

现在,如果我在2013年3月20日调度作业,"NextFireTimeUtc"结果:
DateTime: 01.04.2013 13:00:00(这是UTC时间,现在比当地时区晚两个小时)
LocalDateTime: 01.4.2013 15:00:00

注意,结果的NextFireTimeUtc现在落在本地夏令时内。因此,LocalDateTime也从UTC被"修正"了一个小时。这将导致作业在15:00运行,这不是我想要的。

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

一定有一个简单的方法来处理这个现象,我可能只是错过了一些概念。我很困惑。

编辑:


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

触发点1:每月28日14:00火灾

GetFireTimeAfter now +00 months: 28.03.2013 13:00:00 +00:00 <-这是正确的
getfiretime现在之后+ 01个月:28.04.2013 12:00:00 +00:00
getfiretime现在之后+ 02个月:28.05.2013 12:00:00 +00:00
getfiretime现在之后+ 03个月:28.06.2013 12:00:00 +00:00
getfiretime现在之后+ 04个月:28.07.2013 12:00:00 +00:00
getfiretime现在之后+ 05个月:28.08.2013 12:00:00 +00:00
GetFireTimeAfter now + 06 months: 28.09.2013 12:00:00 +00:00
getfiretime现在之后+ 07个月:28.10.2013 13:00:00 +00:00 <-夏令时已经结束
GetFireTimeAfter now + 08 months: 28.11.2013 13:00:00 +00:00

第一个火灾时间是正确的,因为它仍然属于"冬季"。"summertime"期间的时间被额外减去-1,从而在本地时区加上+2后得到正确的5分钟时间。

触发点1:每月1日14:00火灾

GetFireTimeAfter now +00 months: 01.04.2013 13:00:00 +00:00 <-这是错误的?
getfiretime现在之后+ 01个月:01.05.2013 12:00:00 +00:00
getfiretime现在之后+ 02个月:01.06.2013 12:00:00 +00:00
getfiretime现在之后+ 03个月:01.07.2013 12:00:00 +00:00
getfiretime现在之后+ 04个月:01.08.2013 12:00:00 +00:00
getfiretime现在之后+ 05个月:01.09.2013 12:00:00 +00:00
GetFireTimeAfter now + 06 months: 01.10.2013 12:00:00 +00:00
getfiretime现在之后+ 07个月:01.11.2013 13:00:00 +00:00 <-夏令时已经结束
GetFireTimeAfter now + 08 months: 01.12.2013 13:00:00 +00:00

第一次火灾已经在夏季发生,但它只被-1抵消,导致当地触发时间为15:00。

所以触发器是正常的,除了第一个触发器时间,如果它是在冬季调度的,第一次执行是在夏季。如何处理这种情况?

石英.使用/理解基于cron的触发器和时区/夏令时(夏令时)

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