Thursday, February 8, 2024

[SOLVED] Quartz.net - Repeat on day n, of every m months?

Issue

Using Quartz.NET, I'm trying to create a trigger that:

  1. starts on September 30th
  2. repeats on the last day
  3. repeats every 5 months
  4. would be able to use ITrigger.GetFireTimeAfter() to compute and project the next fire times to display in UI feedback.

Expected:

  • 2017-9-30
  • 2018-2-28
  • 2018-7-31
  • 2018-12-31

I thought I could use a CronTrigger like 0 0 0 L 9/5 ? *.

But, the projected days are:

  • 2017-9-30
  • 2018-9-30
  • 2019-9-30

I could not use CalendarIntervalTrigger either:

For example, if you choose a start time that occurs on January 31st, and have a trigger with unit Month and interval 1, then the next fire time will be February 28th, and the next time after that will be March 28th - and essentially each subsequent firing will occur on the 28th of the month, even if a 31st day exists. If you want a trigger that always fires on the last day of the month - regardless of the number of days in the month, you should use ICronTrigger

Quartz.NET documentation

How can I schedule a trigger like this? Do I have to implement my own trigger and IScheduler from scratch? Or is there a way for me to inject a custom calculation?


Solution

It's not the way how the cron expression works. By defining it "9/5" you just expressed "start at september" and "icrement by 5 month" but there is no fourteenth month. Every month that exceed months count will be cutted so for example 1/5 will evaluate to "January" then "June" and lastly to "November". Another try will overflow months count and cron will start from the begining. So it will start from another "January", then "June" and lastly "November". Look at the expression, if it would work like you want, it wouldn't fit the expression in the next year becouse for example 1/5 would be evaluated in "April"

1/5 => January (2017) +5
1/5 => June (2017) +5
1/5 => November (2017) +5
1/5 => April (2018) +5

which is wrong! becouse April doesn't fit 1/5

This is correct behaviour:

1/5 => January (2017) +5
1/5 => June (2017) +5
1/5 => November (2017) +5
1/5 => January (2018) +5
1/5 => June (2018)
... 

What you really need is tool that works in a different way. I don't think there is some way to force Quartz.NET Cron to work as you want. The only way would be to "replace" Quartz.NET cron evaluator with something different. If you look around a bit, You could find library which I'm an author that implement small domain specific language that should be much more fitted for what you would like to do. I described it here: Evaluate complex time patterns



Answered By - Puchacz
Answer Checked By - Dawn Plyler (WPSolving Volunteer)