Hello
What happens in the months like February and April who does not have 31 days if I set a Recurrjing Job to run every 31 which whould mean the last day of the month? Or for example day 30, which also does not exist in february for instance?
Hello
What happens in the months like February and April who does not have 31 days if I set a Recurrjing Job to run every 31 which whould mean the last day of the month? Or for example day 30, which also does not exist in february for instance?
It should run on the last day of that mothn
You sure about that? I’m not enterily sure that is what will happen.
I was wrong 31 will always match just 31st day of month. If month has no 31st so it won’t run.
However you can use L (which stands for LAST)
0 0 L * * will run on every last day of month
It still does not remove the February problem, L for 31 will work, but 30 won’t exist in February also, so If I say that 30 will run in the end of the month, sometimes it will run on 31 instead of 30 which would make it run in the wrong day in 7 months.
Basically February ruins everything. Day 29 will also be a problem because it may or it may not exist
By the way just tested with L and I got:'L' is not a valid [Day] crontab field value. It must be a numeric value between 1 and 31 (all inclusive).
Hi, Rui. I just tested ir with the ‘L’ CRON keyword and it is in fact as you said. It’s not valid.
But you get get around it by just getting the day number yourself and just concatenate the string. For instance:
var day = DateTime.DaysInMonth(DateTime.UtcNow.Year,2).ToString();
I tested it with minute incrementation only as it would take too long to wait the end of each month to test it. So, this was it:
private static string LigacaoBD = @"*Your Data Source*";
private static int number = 0;
private static string id = "";
var server = new BackgroundJobServer();
BackgroundJob.Enqueue(() => test());
public string Increment()
{
number++;
cron = "*/" + number + " * * * *";
return cron;
}
public void test()
{
using (var connection = JobStorage.Current.GetConnection())
{
foreach (var recurringJob in connection.GetRecurringJobs())
{
recurringJob.Cron = Increment();
}
}
RecurringJob.AddOrUpdate(() => test(), cron);
}
So, bascially, you have to “manually” look for the cron of the recurring job and order a change (otherwise it won’t update) and send it to a string. And then just use that string as the cron.
I tested it with minute incrementation, but you can replace that with the line I showed at the beginning of the about, about the days in month.
Hope it helped.
Try reading this thread, it has a ton of different approaches to the dilemma. The easiest being running the job on the first day of the month instead and substraction a day in your code.
Yes, it can definitely be easier to do this of the first day rather than the last. But it depends on Rui’s problem. If it’s not affected he might be better off just doing it on the first day. If it is, than there are other solutions. I posted mine above. It’s an example and he can adapt it to his own needs.
I will read everything, but I can’t delay, I can advance and that is what I am currently doing right now, 29,30 and 31 are all being processed in 28. But I will read all your suggestions.
Thank you all
Please do, and give feedback on your choice.
Extended cron syntax (with L
) will be supported in Hangfire 1.7.0.
For now, you may schedule your job on 28,29,30,31 days of every month, and add an extra check in your job method:
var today = DateTime.Today;
if (today.Day != DateTime.DaysInMonth(today.Year, today.Month)) return;
You may also checkout a dev branch of Hangfire and build it yourself. It should already support extended cron syntax.