【问题标题】:Calculating the next run time for the task计算任务的下一次运行时间
【发布时间】:2017-02-15 20:55:12
【问题描述】:

我有以下任务的数据结构:

Task{
    Start: 17:00:00
    End:   20:00:00
    Interval: 5
    Days: [1, 2, 3, 6, 7]
}

所以这有点像某些任务的计划设置。我有一个 Windows 服务,它每 5 秒打勾,如果是时候运行任务,它会做一些计算。检查它很简单。例如,我正在检查当前时间的日期是否在Days 数组中,当前时间是否在StartEnd 等之间。所以这个任务将在17:05:0417:10:01 等处执行(近似值为 5 秒)。所以它当前时间接近17:00 + N*5 seconds 它执行一些代码。那工作正常。

我现在正在努力计算未来执行此任务的时间。例如,如果现在是Monday 16:58:30,那么下一次将执行它是Monday 17:05。如果是Friday 18:00,它将在Saturday 17:05 处执行。如果是Monday 18:33,下一次运行是Monday 18:35。当您意识到 Start 可以是 Start: 17:03:00 等运行时间现在发生变化时,困难就来了 17:0817:13 等。

【问题讨论】:

    标签: algorithm scheduled-tasks


    【解决方案1】:
    /// <summary>
    /// Calculates the next run for the task.
    /// </summary>
    /// <param name="task"></param>
    /// <returns></returns>
    public static string GetNextRun(TaskBase task)
    {
        var now = DateTime.Now;
        var currentDay = now.DayOfWeek == DayOfWeek.Sunday ? 7.ToString() : ((int)now.DayOfWeek).ToString();
        var currentTime = now.TimeOfDay;
    
        var startAt = task.StartAt;
    
        //If Days is empty the task will never execute.
        if (task.Days.Length == 0)
        {
            return "Never";
        }
        //If the current day is allowed.
        else if (task.Days.Contains(currentDay))
        {
            //If current time is allowed
            if (currentTime >= task.StartAt && currentTime <= task.StopAt)
            {
                //Start from beginning and add interval till we get a time greater than current day.
                while (startAt < currentTime)
                {
                    startAt = startAt.Add(TimeSpan.FromMinutes(task.IntervalInMinutes));
                }
    
                //If we are still in the allowed range return this time.
                if (startAt >= task.StartAt && startAt <= task.StopAt)
                {
                    return now.Date.Add(startAt).ToString();
                }
            }
            //If we are before starting point just return the first tick.
            else if (currentTime < task.StartAt)
            {
                startAt = startAt.Add(TimeSpan.FromMinutes(task.IntervalInMinutes));
    
                return now.Date.Add(startAt).ToString();
            }
        }
    
        startAt = task.StartAt;
    
        //If the current day is not allowed or the day is allowed but currentTime > task.StopAt.
        //Add days until we get next allowed day and return the first tick.
        while (true)
        {
            now = now.AddDays(1);
            currentDay = now.DayOfWeek == DayOfWeek.Sunday ? 7.ToString() : ((int)now.DayOfWeek).ToString();
    
            if (task.Days.Contains(currentDay))
            {
                startAt = startAt.Add(TimeSpan.FromMinutes(task.IntervalInMinutes));
    
                return now.Date.Add(startAt).ToString();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-12-28
      • 2017-08-12
      • 2015-05-19
      • 1970-01-01
      • 1970-01-01
      • 2017-05-24
      • 1970-01-01
      • 1970-01-01
      • 2022-01-24
      相关资源
      最近更新 更多