Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getNextFireTime of my existing job

I tried Quartz.com documentation & googled for couple for hours...but could not find single good article on how to get Next Job (which is supposr to fire in future).

I am using CronTrigger Expression to Schedule jobs, using VB.net (winforms). jobs works fine...however I would like my users to see when will it FIRE next. I am storing CronExpression in my database, Can I use that Expression to show next Fire Date/Time to my end users? or if there is any other way possible please advise (with a simple samply).

Thanks

Edit

Following Code Returns next job will fire after 12 minutes instead of 20 minute

    Dim exp As CronExpression = New CronExpression("0 0/20 * * * ?")
    Dim nextFire As String = exp.GetNextValidTimeAfter(DateTime.Now)
    MsgBox(nextFire)
like image 460
highwingers Avatar asked Nov 29 '12 19:11

highwingers


2 Answers

You can create a new JobKey

JobKey jobKey = new JobKey(jobName, groupName);

and use the key to fetch the job detail:

var detail = scheduler.GetJobDetail(jobKey);

this is a simple function which does what you're looking for:

    private DateTime getNextFireTimeForJob(IScheduler scheduler, string jobName, string groupName = "")
    {
        JobKey jobKey = new JobKey(jobName, groupName);
        DateTime nextFireTime = DateTime.MinValue;

        bool isJobExisting = Scheduler.CheckExists(jobKey);
        if (isJobExisting)
        {
            var detail = scheduler.GetJobDetail(jobKey);
            var triggers = scheduler.GetTriggersOfJob(jobKey);

            if (triggers.Count > 0)
            {
                var nextFireTimeUtc = triggers[0].GetNextFireTimeUtc();
                nextFireTime = TimeZone.CurrentTimeZone.ToLocalTime(nextFireTimeUtc.Value.DateTime);
            }
        }

        return (nextFireTime);
    }

It works only if you have one trigger per job.
If there's more than one trigger in your job you can loop through them:

foreach (ITrigger trigger in triggers)
{
    Console.WriteLine(jobKey.Name);
    Console.WriteLine(detail.Description);
    Console.WriteLine(trigger.Key.Name);
    Console.WriteLine(trigger.Key.Group);
    Console.WriteLine(trigger.GetType().Name);
    Console.WriteLine(scheduler.GetTriggerState(trigger.Key));
    DateTimeOffset? nextFireTime = trigger.GetNextFireTimeUtc();
    if (nextFireTime.HasValue)
    {
        Console.WriteLine(TimeZone.CurrentTimeZone.ToLocalTime(nextFireTime.Value.DateTime).ToString());
    }
}

or using Linq (System.Linq) :

 var myTrigger = triggers.Where(f => f.Key.Name == "[trigger name]").SingleOrDefault();
like image 161
LeftyX Avatar answered Sep 18 '22 18:09

LeftyX


If you already know the cronExpression then you can call GetNextValidTimeAfter , eg

CronExpression exp = new CronExpression("0 0 0/1 1/1 * ? *");
var nextFire = exp.GetNextValidTimeAfter(DateTime.Now);
Console.WriteLine(nextFire);

and if you want more fire times, then

for(int i=0 ; i< 9; i++)
{
    if (nextFire.HasValue)
    {
        nextFire = exp.GetNextValidTimeAfter(nextFire.Value);        
        Console.WriteLine(nextFire);
     }
}

If you are looking for a more general way of showing next fire times for existing jobs, then check out the answer to this question which works even if you aren't using cron expressions. This is for Quartz Version 2

The Quartz Version 1 way of getting job and trigger information is something like the method below.

 public void GetListOfJobs(IScheduler scheduler)
 {
    var query =
        (from groupName in scheduler.JobGroupNames
         from jobName in scheduler.GetJobNames(groupName)
         let triggers = scheduler.GetTriggersOfJob(jobName, groupName)
         select new 
            { 
                groupName, 
                jobName, 
                triggerInfo = (from trigger in triggers select trigger) 
            }
        );

   foreach (var r in query)
   {
       if (r.triggerInfo.Count() == 0)
       {
           var details = String.Format("No triggers found for : Group {0}  Job {1}", r.groupName, r.jobName);
           Console.WriteLine(details);                   
       }

       foreach (var t in r.triggerInfo)
       {
           var details = String.Format("{0,-50} {9} Next Due {1,30:r} Last Run {2,30:r}  Group {3,-30}, Trigger {4,-50} {5,-50} Scheduled from {6:r} Until {7,30:r} {8,30:r} ",
               t.JobName,
               t.GetNextFireTimeUtc().ToLocalTime(), 
               t.GetPreviousFireTimeUtc().ToLocalTime(),
               t.JobGroup, 
               t.Name, 
               t.Description,
               t.StartTimeUtc.ToLocalTime(), 
               t.EndTimeUtc.ToLocalTime(), 
               t.FinalFireTimeUtc.ToLocalTime(),
               ((t.GetNextFireTimeUtc() > DateTime.UtcNow) ? "Active  " : "InActive")
               );

           Console.WriteLine(details);

       }
   }

}

like image 31
sgmoore Avatar answered Sep 18 '22 18:09

sgmoore