3

For sake of an example lets use the following cron expression: "0 0 14 1 * ?"
-> Fire on the 1st day of every month at 14:00 hours.

I used the Quartz CronScheduleBuilder to build the expession, but this is irrelevant.

My Local timezone is UTC+01:00 and the summertime (this year) begins on 31.03.2013 2:00, where the time is adjusted to 3:00.

When i schedule a new Job using the proposed trigger on lets say 20.02.2013, Quartz calculates the System.DateTimeOffset for the "NextFireTimeUtc" correctly to:
DateTime: 01.03.2013 13:00:00 (this is the UTC time, which is one hour behind the local timezone)
LocalDateTime: 01.03.2013 14:00:00

The job will correctly trigger on 14:00 hours as specified.

Now if i schedule the job on 20.03.2013, the "NextFireTimeUtc" results in:
DateTime: 01.04.2013 13:00:00 (this is the UTC time, which is now two hours behind the local timezone)
LocalDateTime: 01.04.2013 15:00:00

Notice, that the resulting NextFireTimeUtc now falls within the local summertime. As a result, the LocalDateTime was also "corrected" by an additional hour from the UTC. This results in the job running at 15:00 hours, which is not what i want.

What i (obviously) expected is that the "14" in the cron expression should always result in the trigger firing at 14:00, even during summertime.

There must be an easy way to deal with this phenomenon, i am probably just missing something conceptional. I am confused.

EDIT:
The problem seems to be, that Quartz calculates the first NextFireTimeUtc depending on the current timezone information. To test this, i scheduled two different cron triggers and called GetFireTimeAfter() on the trigger with an increasing offset to view the resulting fire times over the year.

Trigger 1: Fire on the 28th of every month at 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

The first fire time is correct, since it still falls into "wintertime". The times during "summertime" are off by an additional -1, resulting in the correct fire time after the local timezone adds +2.

Trigger 1: Fire on the first day of every month at 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

The first fire already falls within summertime, but its only offset by -1, resulting in a local trigger time of 15:00.

So the trigger is fine, except for the first trigger time, if its scheduled during wintertime and the first execution falls within summertime. How to handle this?

4

1 回答 1

2

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

有关详细信息,请参阅此答案

于 2013-03-28T18:24:51.230 回答