私はWindowsサービスを構築しています。設定可能な間隔でさまざまなバックグラウンドタスクを処理したいと考えています。月間スケジュールのタイマー間隔を計算するにはどうすればよいですか?
タイマーが何らかのタスクを開始するまでに待つ必要がある時間の長さを計算する方法がわかりません。
私は、タスク、および間隔のタイプに対するStartDate
保存:ルール
...私は毎日釘付けしましたが、毎月をする方法を考え出すことができない、毎日、毎週、毎月など以下のとおりです。
StartDate
が将来的にある場合は、Now
とStartDate
間の時間の長さを待ちます。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;
}
は' TimeSpan.FromDaysされていません。 –
@IanMercer:おそらく...私は最終的にそれを最適化せずに計算で遊んでいる多くの多くのものを試しました:) – BG100