public async Task UpdateSchedule(Check check)
        {
            await RemoveSchedule(check);

            if (!check.Active)
            {
                return;
            }
            var type = _jobHelper.GetJobForCheck(check);
            IDictionary <string, object> data = new Dictionary <string, object>
            {
                ["CheckID"] = check.ID,
            };
            var job = JobBuilder.Create(type)
                      .WithIdentity(GetJobKeyForCheck(check))
                      .SetJobData(new JobDataMap(data))
                      .Build();

            await _scheduler.AddJob(job, false, true);

            var timeZone = await _jobHelper.GetTimeZone();

            foreach (var schedule in check.Schedules.Where(x => x.Active))
            {
                if (CronExpression.IsValidExpression(schedule.Expression))
                {
                    var trigger = TriggerBuilder.Create()
                                  .WithIdentity(GetTriggerKeyForSchedule(schedule))
                                  .WithCronSchedule(schedule.Expression, x => x.InTimeZone(timeZone))
                                  .ForJob(job)
                                  .UsingJobData("ScheduleID", schedule.ID)
                                  .Build();

                    await _scheduler.ScheduleJob(trigger);
                }
                else
                {
                    _logger.LogError($"Failed to create schedule for ID {schedule.ID} on check {check.Name} ({check.ID}): {schedule.Expression}");
                }
            }
        }
 public async Task <ValidateCronResult> ValidateCronExpressionAsync([FromBody] string cron, bool?validateOnly = null)
 {
     try
     {
         var expression = new CronExpression(cron)
         {
             TimeZone = await _jobHelper.GetTimeZone()
         };
         if (validateOnly ?? false)
         {
             return(new ValidateCronResult
             {
                 Valid = true
             });
         }
         DateTimeOffset?time  = DateTimeOffset.UtcNow;
         var            count = 5;
         var            next  = "";
         while (count > 0)
         {
             count--;
             time = expression.GetTimeAfter(time.Value);
             if (!time.HasValue)
             {
                 break;
             }
             next += time.Value.LocalDateTime.ToString("yyyy-mm-dd HH:mm:ss") + "\n";
         }
         next += "\n" + expression.GetExpressionSummary();
         return(new ValidateCronResult
         {
             Valid = true,
             Next = next
         });
     }
     catch (Exception e)
     {
         return(new ValidateCronResult
         {
             Valid = false,
             Error = e.Message
         });
     }
 }