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

标签 c# timezone quartz-scheduler quartz.net

举个例子,让我们使用以下 cron 表达式:“0 0 14 1 * ?”
-> 在每月第一天的 14:00 触发。

我使用 Quartz CronScheduleBuilder 来构建表达式,但这无关紧要。

我的本​​地时区是 UTC+01:00,夏令时(今年)从 31.03.2013 2:00 开始,时间调整为 3:00。

当我使用提议的触发器安排新作业时,比如说 2013 年 2 月 20 日,Quartz 正确计算“NextFireTimeUtc”的 System.DateTimeOffset 为:
日期时间:01.03.2013 13:00:00(UTC时间,比本地时区晚一小时)
LocalDateTime:01.03.2013 14:00:00

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

现在,如果我将作业安排在 2013 年 3 月 20 日,则“NextFireTimeUtc”结果为:
日期时间: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() 并增加了偏移量,以查看一年中产生的触发时间。

触发器一:每月28日14:00触发

GetFireTimeAfter now + 00 months: 28.03.2013 13:00:00 +00:00 <- this is correct
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 <- summertime already ended
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 <- this is wrong?
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 <- summertime already ended
GetFireTimeAfter now + 08 months: 01.12.2013 13:00:00 +00:00

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

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

最佳答案

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

参见 this answer了解详情。

关于c# - Quartz.NET - 使用/理解基于 cron 的触发器和时区/夏令时(夏令时),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15661268/

相关文章:

c# - 如何使用 app.config 阻止 TextWriterTraceListener 附加?

c# - 每个任务都有单独的线程池

c# - 使用正则表达式解析数据

android - 如何处理 JodaTime 和 Android 的时区数据库差异?

c# - 如何为每个线程设置时区?

mysql - 如何更改 Laravel 项目的 MySQL DB UTC 时间?

java - 如何让StatefulJobs连续运行(而不是同时运行)?

java - Quartz为已经存在的作业添加触发器

c# - Url 更改后,TFS 本地项目无法连接

java - 添加到触发器的 JobData 未传递给 Quartz 中的作业