작업

2017-02-15 2 views
0

에 대한 다음 실행 시간을 계산 I 작업에 대한 다음과 같은 데이터 구조가 있습니다작업

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

그래서 일부 작업에 대한 일정 설정과 같은입니다. 나는 각각의 5 초를 틱하고 작업을 실행할 시간이라면 몇 가지 계산을 수행하는 Windows 서비스를 가지고있다. 그것을 확인하는 것은 아주 간단합니다. 예를 들어 현재 시간이 StartEnd 사이 인 경우 현재 시간이 Days 배열인지 확인하고 있습니다. 따라서이 작업은 17:05:04, 17: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(); 
     } 
    } 
}