I want Quartz to execute job every on the fifth day of every third week of every fifth month. I do it like this: 0 0 10 ? */5 5#3
The problem is cron scheduler is bound to year in this case. So actually it executes schedule on 1, 6, 11 month of every year. But I want it to execute transparently starting from current month. Like 4, 9, 2 next year, 7 next year e.t.c. How can one do it?
I know there's CalendarIntervalSchedule which does this but it doesn't allow me to do "fifth day of every third week".
Quartz scheduler lets you specify more than one CronTrigger per job. So instead of creating a single multipurpose expression you can create few smaller expressions to work together.
I came up with these:
0 0 10 ? 1,6,11 5#3 2015/5
0 0 10 ? 4,9 5#3 2016/5
0 0 10 ? 2,7,12 5#3 2017/5
0 0 10 ? 5,10 5#3 2018/5
0 0 10 ? 3,8 5#3 2019/5
The only drawback is that you would have to specify the starting years at the very beginning, but I guess you can automate it easily.
Good luck! ;)
For my task I found a better solution. I created a calendar which will include only months starting at specified date with specified interval. All other months will be rejected.
It's easier for me cause I don't need to create/manage a lot of triggers for a job.
[Serializable]
public class MonthIntervalCalendar : BaseCalendar
{
DateTime _startAt;
int _interval;
/// <summary>
/// Initializes a new instance of the <see cref="MonthIntervalCalendar"/> class.
/// </summary>
public MonthIntervalCalendar(DateTime startAt, int interval)
{
_startAt = startAt;
_interval = interval;
}
/// <summary>
/// Initializes a new instance of the <see cref="MonthIntervalCalendar"/> class.
/// </summary>
/// <param name="baseCalendar">The base calendar.</param>
public MonthIntervalCalendar(DateTime startAt, int interval, ICalendar baseCalendar)
{
_startAt = startAt;
_interval = interval;
CalendarBase = baseCalendar;
}
public override bool IsTimeIncluded(DateTimeOffset timeStampUtc)
{
if (!base.IsTimeIncluded(timeStampUtc))
return false;
if (timeStampUtc < _startAt)
return false;
var months = (timeStampUtc.Month - _startAt.Month) + 12 * (timeStampUtc.Year - _startAt.Year);
var included = months % _interval == 0;
return included;
}
/// <summary>
/// Determine the next time (in milliseconds) that is 'included' by the
/// Calendar after the given time.
/// <para>
/// Note that this Calendar is only has full-day precision.
/// </para>
/// </summary>
public override DateTimeOffset GetNextIncludedTimeUtc(DateTimeOffset timeUtc)
{
timeUtc = base.GetNextIncludedTimeUtc(timeUtc);
while (!IsTimeIncluded(timeUtc))
{
var nextTime = timeUtc.AddMonths(1);
timeUtc = base.GetNextIncludedTimeUtc( new DateTime(nextTime.Year, nextTime.Month, 1) );
}
return timeUtc;
}
/// <summary>
/// Creates a new object that is a copy of the current instance.
/// </summary>
/// <returns>A new object that is a copy of this instance.</returns>
public override object Clone()
{
MonthIntervalCalendar clone = (MonthIntervalCalendar)base.Clone();
clone._interval = _interval;
clone._startAt = _startAt;
return clone;
}
public override int GetHashCode()
{
int baseHash = 0;
if (GetBaseCalendar() != null)
baseHash = GetBaseCalendar().GetHashCode();
return _startAt.GetHashCode() + _interval + 5 * baseHash;
}
public bool Equals(MonthIntervalCalendar obj)
{
if (obj == null)
return false;
bool baseEqual = GetBaseCalendar() == null || GetBaseCalendar().Equals(obj.GetBaseCalendar());
return baseEqual && obj._startAt.Equals(_startAt) && obj._interval.Equals(_interval);
}
public override bool Equals(object obj)
{
if ((obj == null) || !(obj is MonthIntervalCalendar))
return false;
return Equals((MonthIntervalCalendar)obj);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With