如何计算每月计划的计时器间隔?

时间:2016-05-25 16:04:44

标签: c# datetime intervals

我正在构建一个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

正如你所看到的,它最终会有点不对劲。我需要什么计算才能正确计算出小时数?

1 个答案:

答案 0 :(得分:1)

试试这段代码:

def chart(request):     
    if 'checks[]' in request.GET and request.GET['checks[]']:
        #getting id's of selected tags
        chosen = request.GET.getlist('checks[]')
        tags = Tag.objects.filter(id__in = chosen)
        fig=Figure()
        ax=fig.add_subplot(111)
        strIdTags = ""
        #getting all values of all selected tags
        for tag in tags:
            if Values.objects.filter(tag = tag.id).count > 0:
                #values of one tag
                values = Values.objects.filter(tag = tag.id)
                strIdTags+=str(tag.id)
                strIdTags+="; "
                x = []
                y = []
                #all values of one tag
                for value in values:
                    y.append(value.value)
                    x.append(value.datetime)
                    #ax.plot_date(value.value, value.datetime, '-')
                ax.plot_date(x, y, '-')
                ax.annotate("Tag "+str(tag.id), (x[0],y[0]),
                arrowprops=dict(facecolor='black', shrink=0.05))
        ax.xaxis.set_major_formatter(DateFormatter('%d/%m/%Y - %H:%M:%S'))
        ax.set_title("Values of Tags: "+strIdTags)
        ax.set_xlabel("Date-Time")
        ax.set_ylabel("Values")
        fig.autofmt_xdate()
        canvas=FigureCanvas(fig)
        response=HttpResponse(content_type='image/png')
        canvas.print_png(response)
        return response