GetNext ? issue ?
Hi,
may be I am wrong somewhere
but with the following cron, 0 18 16 ? * SUN,MON,TUE,WED,THU,FRI,SAT
// I call it at <00:16:16 22/04/2025>
while (!cancellationToken.IsCancellationRequested)
{
DateTime now = DateTime.UtcNow;
DateTime? nextExecTime;
CronExpression nextExecCron = CronExpression.Parse(treatment.Cron, CronFormat.IncludeSeconds);
nextExecTime = nextExecCron.GetNextOccurrence(now.**AddMinutes**(1));
// I got <00:18:16 22/04/2025>
int delay = (int)(nextExecTime.Value - DateTime.Now).TotalMilliseconds;
//wait for delay
} //while
I call it at <00:16:18 TUE> + ONE MINUTE
I got <00:18:16 22/04/2025> ==> SO BACK IN TIME ?? should have <00:18:16 23/04/2025>
if i debug and wait for several minutes, i got the same result...
thanks for your help
It seams that with local time, it works...? but why ?
The delay variable is calculated using the DateTime.Now property, which returns a date time in a local time zone, while next execution is using UTC. Try to modify the line to the following one:
int delay = (int)(nextExecTime.Value - DateTime.UtcNow).TotalMilliseconds;
ok, may be I do a small mistake on this, but it is not the delay calculation the problem. It is the GETNEXT !
this code is not working : the second call to getnext return the same date even one minute after and delay becomes negative
do you see what is wrong ?
while (!cancellationToken.IsCancellationRequested)
{
try
{
DateTime now = DateTime.UtcNow;
DateTime? nextExecTime;
CronExpression nextExecCron = CronExpression.Parse("45 14 ? * SUN,MON,TUE,WED,THU,FRI,SAT", CronFormat.Standard);
nextExecTime = nextExecCron.GetNextOccurrence(now);
if (nextExecTime > now.Date.AddDays(1))
{ //si demain on arrete
nextExecTime = null;
}
if (nextExecTime.HasValue)
{
int delay = (int)(nextExecTime.Value - now).TotalMilliseconds;
if (delay > 0)
{
_tracer.Debug("schedule {Id} is awaited for {delay}", treatment.ScheduleId, delay);
cancellationToken.WaitHandle.WaitOne(delay);
if (!cancellationToken.IsCancellationRequested)
{
//execute
//we wait the minute after...
cancellationToken.WaitHandle.WaitOne(60000);
}
}
else { return; }
}
else { return; }
}
catch (Exception ex)
{
}
}
this code works
try
{
DateTimeOffset DTnow = DateTimeOffset.Now;
DateTime? nextExecTime;
CronExpression nextExecCron = CronExpression.Parse(treatment.Cron, CronFormat.Standard);
DateTimeOffset? next = nextExecCron.GetNextOccurrence(DTnow, TimeZoneInfo.Local);
nextExecTime = next?.DateTime;
if (nextExecTime > DTnow.Date.AddDays(1))
{ //si demain on arrete
nextExecTime = null;
}
if (nextExecTime.HasValue)
{
int delay = (int)(nextExecTime.Value - DateTime.Now).TotalMilliseconds;
if (delay > 0)
{
_tracer.Debug("schedule {Id} is awaited for {delay}", treatment.ScheduleId, delay);
cancellationToken.WaitHandle.WaitOne(delay);
if (!cancellationToken.IsCancellationRequested)
{
_tracer.Debug("schedule {Id} is executed now", treatment.ScheduleId);
new DdpScheduleCRUD(_connectionProvider).ApplySupSchedule(treatment.ScheduleId);
//we wait the minute after...
cancellationToken.WaitHandle.WaitOne(60000);
}
}
else { return; }
}
else { return; }
}