【发布时间】:2016-05-25 16:04:44
【问题描述】:
我正在构建一个 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
正如你所看到的,它在最后有点不对劲。我需要哪些计算才能正确计算出小时数?
【问题讨论】:
-
TimeSpan.FromDays((a - b).TotalDays)不等于(a-b)吗? -
@IanMercer:可能......我已经尝试了很多东西,只是我在玩计算而没有最终优化它:)