Search code examples
quartz.netcronexpression

Quartz.net CRON expression always returns last day of month?


I'm a quartz newbie.

I'm simply attempting to find out if Quartz.net can, given a start date (possibly in the past), an end date and an interval calculate the correct date occurances - it might not be Quartz's primary use case but it appears possible from what i can discover of the API.

So given this fragment:

var exp = new CronExpression("0 0 0 1/7 * ? *");

    var next = exp.GetNextValidTimeAfter(new DateTime(2012, 1, 1, 12, 30, 00).ToUniversalTime());
    while (next < DateTime.Parse("30 Oct 2012"))
    {
        next = exp.GetNextValidTimeAfter(next.Value);
        System.Diagnostics.Debug.WriteLine(next);
    }

The results appear to be (truncated):

14/01/2012 11:00:00 a.m. +00:00

21/01/2012 11:00:00 a.m. +00:00

28/01/2012 11:00:00 a.m. +00:00

31/01/2012 11:00:00 a.m. +00:00

7/02/2012 11:00:00 a.m. +00:00

14/02/2012 11:00:00 a.m. +00:00

21/02/2012 11:00:00 a.m. +00:00

28/02/2012 11:00:00 a.m. +00:00

29/02/2012 11:00:00 a.m. +00:00

7/03/2012 11:00:00 a.m. +00:00

Errr... It seems Quartz's CRON expression always includes the last day of month and essentially calculates the next date from there? Or is my expectation / understanding of quartz / cron wrong?

Also these results seem to be backed up using http://www.cronmaker.com/...

Thanks!


Solution

  • I don't think you can't achieve what you're looking for with a cron expression.

    If you download and use Quartz.Net 2.x you can use a new type of trigger called CalendarIntervalTrigger which can be used to manage different interval units.

    I've tested this bit of code and it works the way you expect:

    DateTimeOffset startCalendar = DateBuilder.DateOf(11, 0, 0, 14, 1, 2012);
    
    var weeklyTrigger = new CalendarIntervalTriggerImpl
    {
        StartTimeUtc = startCalendar,
        RepeatIntervalUnit = IntervalUnit.Week,
        RepeatInterval = 1  // every one week;
    };
    
    IList<DateTimeOffset> fireTimes = TriggerUtils.ComputeFireTimes(weeklyTrigger, null, 10);
    
    foreach (var item in fireTimes)
    {
        Console.WriteLine(item);
    }
    Console.ReadLine();
    

    Result:

    14/01/2012 11:00:00 +00:00
    21/01/2012 11:00:00 +00:00
    28/01/2012 11:00:00 +00:00
    04/02/2012 11:00:00 +00:00
    11/02/2012 11:00:00 +00:00
    18/02/2012 11:00:00 +00:00
    25/02/2012 11:00:00 +00:00
    03/03/2012 11:00:00 +00:00
    10/03/2012 11:00:00 +00:00
    17/03/2012 11:00:00 +00:00