2016-05-25 9 views
0

私はWindowsサービスを構築しています。設定可能な間隔でさまざまなバックグラウンドタスクを処理したいと考えています。月間スケジュールのタイマー間隔を計算するにはどうすればよいですか?

タイマーが何らかのタスクを開始するまでに待つ必要がある時間の長さを計算する方法がわかりません。

私は、タスク、および間隔のタイプに対するStartDate保存:ルール

...私は毎日釘付けしましたが、毎月をする方法を考え出すことができない、毎日、毎週、毎月など以下のとおりです。

  • StartDateが将来的にある場合は、NowStartDate間の時間の長さを待ちます。

  • StartDateが過去の場合は、StartDateと同じ日の曜日と現在の翌月のタスクを開始します。したがってStartDateが3月15日09:00にあり、今日が5月25日である場合、次回のタスクは6月15日09:00に実行されます。

私はこれまでにこれを得ました。

using System; 
using System.Collections.Generic; 
using System.Linq; 

public class Program 
{ 
    public static void Main() { 

     // Test cases 
     var times = new Dictionary<DateTime,TimeSpan> { 
      { new DateTime(2016, 3, 1, 9, 0, 0), TimeSpan.FromHours(2016)}, 
      { new DateTime(2016, 3, 5, 3, 0, 0), TimeSpan.FromHours(1926)}, 
      { new DateTime(2016, 3, 5, 9, 0, 0), TimeSpan.FromHours(1920)}, 
      { new DateTime(2016, 3, 5, 15, 0, 0), TimeSpan.FromHours(1914)}, 
      { new DateTime(2016, 3, 24, 3, 0, 0), TimeSpan.FromHours(1470)}, 
      { new DateTime(2016, 3, 24, 9, 0, 0), TimeSpan.FromHours(1464)}, 
      { new DateTime(2016, 3, 24, 15, 0, 0), TimeSpan.FromHours(1458)}, 
      { new DateTime(2016, 4, 19, 9, 0, 0), TimeSpan.FromHours(840)}, 
      { new DateTime(2016, 4, 24, 3, 0, 0), TimeSpan.FromHours(726)}, 
      { new DateTime(2016, 4, 24, 9, 0, 0), TimeSpan.FromHours(720)}, 
      { new DateTime(2016, 4, 24, 15, 0, 0), TimeSpan.FromHours(714)}, 
      { new DateTime(2016, 4, 24, 21, 0, 0), TimeSpan.FromHours(708)}, 
      { new DateTime(2016, 5, 6, 3, 0, 0), TimeSpan.FromHours(438)}, 
      { new DateTime(2016, 5, 24, 3, 0, 0), TimeSpan.FromHours(6)}, 
      { new DateTime(2016, 5, 24, 9, 0, 0), TimeSpan.FromHours(0)}, 
      { new DateTime(2016, 5, 24, 15, 0, 0), TimeSpan.FromHours(738)}, 
      { new DateTime(2016, 5, 26, 3, 0, 0), TimeSpan.FromHours(702)}, 
      { new DateTime(2016, 5, 26, 9, 0, 0), TimeSpan.FromHours(696)}, 
      { new DateTime(2016, 5, 26, 15, 0, 0), TimeSpan.FromHours(690)}, 
      { new DateTime(2016, 6, 24, 3, 0, 0), TimeSpan.FromHours(6)}, 
      { new DateTime(2016, 6, 24, 9, 0, 0), TimeSpan.FromHours(0)}, 
      { new DateTime(2016, 6, 24, 15, 0, 0), TimeSpan.FromHours(714)}, 
      { new DateTime(2016, 7, 6, 3, 0, 0), TimeSpan.FromHours(438)}, 
      { new DateTime(2016, 7, 6, 9, 0, 0), TimeSpan.FromHours(432)}, 
      { new DateTime(2016, 7, 6, 15, 0, 0), TimeSpan.FromHours(426)}, 
      { new DateTime(2016, 7, 24, 3, 0, 0), TimeSpan.FromHours(6)}, 
      { new DateTime(2016, 7, 24, 9, 0, 0), TimeSpan.FromHours(0)}, 
      { new DateTime(2016, 7, 24, 15, 0, 0), TimeSpan.FromHours(738)}, 

     }; 


     var startTime = new DateTime(2016, 05, 24, 09, 00, 00); 
     var last = times.First().Key; 


     foreach (var time in times) { 

      var now = time.Key; 
      var expected = time.Value; 

      var timer = startTime.TimeOfDay - now.TimeOfDay; 

      if (now <= startTime)     
       timer += TimeSpan.FromDays((startTime.Date - now.Date).TotalDays); 
      else 
       timer += TimeSpan.FromDays((now.Date.AddMonths(1) - now.Date).TotalDays);     

      if (last.Date != now.Date) Console.WriteLine(); 
      Console.WriteLine($"{now:yyyy-MM-dd HH:mm} -> {startTime:yyyy-MM-dd HH:mm} = {timer:dd\\.hh} {(timer != expected ? "EXPECTED " + expected.ToString("dd\\.hh") : "CORRECT  ")}"); 

      last = now; 

     }   
    }  
} 

生成:ここでテストケースの数を取得し、(テストケースごとに)現在の時刻との間の時間数を計算しようとするテストアプリケーション、およびタスクの固定された開始時間であります次の出力:

2016-03-01 09:00 -> 2016-05-24 09:00 = 84.00 CORRECT  

2016-03-05 03:00 -> 2016-05-24 09:00 = 80.06 CORRECT  
2016-03-05 09:00 -> 2016-05-24 09:00 = 80.00 CORRECT  
2016-03-05 15:00 -> 2016-05-24 09:00 = 79.18 CORRECT  

2016-03-24 03:00 -> 2016-05-24 09:00 = 61.06 CORRECT  
2016-03-24 09:00 -> 2016-05-24 09:00 = 61.00 CORRECT  
2016-03-24 15:00 -> 2016-05-24 09:00 = 60.18 CORRECT  

2016-04-19 09:00 -> 2016-05-24 09:00 = 35.00 CORRECT  

2016-04-24 03:00 -> 2016-05-24 09:00 = 30.06 CORRECT  
2016-04-24 09:00 -> 2016-05-24 09:00 = 30.00 CORRECT  
2016-04-24 15:00 -> 2016-05-24 09:00 = 29.18 CORRECT  
2016-04-24 21:00 -> 2016-05-24 09:00 = 29.12 CORRECT  

2016-05-06 03:00 -> 2016-05-24 09:00 = 18.06 CORRECT  

2016-05-24 03:00 -> 2016-05-24 09:00 = 00.06 CORRECT  
2016-05-24 09:00 -> 2016-05-24 09:00 = 00.00 CORRECT  
2016-05-24 15:00 -> 2016-05-24 09:00 = 30.18 CORRECT  

2016-05-26 03:00 -> 2016-05-24 09:00 = 31.06 EXPECTED 29.06 
2016-05-26 09:00 -> 2016-05-24 09:00 = 31.00 EXPECTED 29.00 
2016-05-26 15:00 -> 2016-05-24 09:00 = 30.18 EXPECTED 28.18 

2016-06-24 03:00 -> 2016-05-24 09:00 = 30.06 EXPECTED 00.06 
2016-06-24 09:00 -> 2016-05-24 09:00 = 30.00 EXPECTED 00.00 
2016-06-24 15:00 -> 2016-05-24 09:00 = 29.18 CORRECT  

2016-07-06 03:00 -> 2016-05-24 09:00 = 31.06 EXPECTED 18.06 
2016-07-06 09:00 -> 2016-05-24 09:00 = 31.00 EXPECTED 18.00 
2016-07-06 15:00 -> 2016-05-24 09:00 = 30.18 EXPECTED 17.18 

2016-07-24 03:00 -> 2016-05-24 09:00 = 31.06 EXPECTED 00.06 
2016-07-24 09:00 -> 2016-05-24 09:00 = 31.00 EXPECTED 00.00 
2016-07-24 15:00 -> 2016-05-24 09:00 = 30.18 CORRECT 

ご覧のとおり、最後に向かって少し間違っています。何時間も正しく計算するために必要な計算は何ですか? - ( - B) ``と `同等の(b)の.TotalDays()

foreach (var time in times) 
{ 
    var now = time.Key; 
    var expected = time.Value;     
    TimeSpan timer; 
    if (now <= startTime) { 
     // no need to do anything here - just substract 
     timer = startTime - now; 
    } 
    else { 
     // normalize start time to current month 
     var normalized = new DateTime(now.Year, now.Month, startTime.Day, startTime.Hour, startTime.Minute, startTime.Second); 
     if (normalized >= now) { 
       // normalized date is later in the same month - substract 
       timer = normalized - now; 
     } 
     else { 
       // normalized date is before current - move to next month 
       timer = normalized.AddMonths(1) - now; 
     } 
    }     

if (last.Date != now.Date) Console.WriteLine(); 
    Console.WriteLine($"{now:yyyy-MM-dd HH:mm} -> {startTime:yyyy-MM-dd HH:mm} = {timer:dd\\.hh} {(timer != expected ? "EXPECTED " + expected.ToString("dd\\.hh") : "CORRECT  ")}"); 
    last = now; 
} 
+0

は' TimeSpan.FromDaysされていません。 –

+0

@IanMercer:おそらく...私は最終的にそれを最適化せずに計算で遊んでいる多くの多くのものを試しました:) – BG100

答えて

1

は、このコードを試してみてください?
+0

これは完璧です、ありがとうございます。テストされ、必要に応じて正確に動作します:) – BG100

関連する問題