2017-02-15 4 views
0

のための次の実行時間を計算し、私は仕事のために次のようなデータ構造を持っている:タスク

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

だから、これはいくつかのタスクのスケジュール設定のようなものです。私は5秒ごとに目を向けるWindowsサービスを持っていて、タスクを実行する時間があればいくつかの計算を行います。それを確認するのはとても簡単です。たとえば、現在の時刻がStartEndの間である場合、現在の時刻がDaysの配列であるかどうかをチェックしています。このタスクは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です。 17:03:00ので、実行している時間が今17:08シフトされ、17:13など

答えて

0
/// <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(); 
     } 
    } 
} 
:あなたはスタートはスタートのようなものにできることを実現する際の困難が来ます