将TimeRange拆分为基于日期的列表

时间:2017-03-20 17:30:17

标签: c# datetime

我有一个以开头和结尾为界的日期范围,我希望得到一个范围列表,将原始范围分成各个日期的范围。因此1月1日到1月7日将返回7个范围,每个范围内一个范围。

基本上我需要的是:

var start = new DateTime(2017, 08, 05, 09, 00, 00);
var end = new DateTime(2017, 08, 07, 16, 00, 00);

var splittedTimeRanges = SplitDate(start, end);
// splittedTimeRanges[0]
//{05.08.2017 9:00:00 - 06.08.2017 00:00:00 | 0.15:00} 
// splittedTimeRanges[1]
//{06.08.2017 00:00:00 - 07.08.2017 00:00:00 | 0.24:00}
// splittedTimeRanges[2]
//{07.08.2017 00:00:00 - 07.08.2017 16:00:00 | 0.16:00}

我希望避免使用Tuple和第三方库,例如this。有没有办法让干净的短代码来实现这个目标?

1 个答案:

答案 0 :(得分:1)

我认为这会为你做到:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TimeSplit
{
    class Program
    {
        static void Main(string[] args)
        {
            var range = new DateRange()
            {
                Start = new DateTime(2017, 08, 05, 09, 00, 00),
                End = new DateTime(2017, 08, 07, 16, 00, 00)
            };

            foreach (var r in SplitInToDays(range))
            {
                Console.WriteLine($"{r.Start} - {r.End} - {r.Duration}");
            }
            Console.ReadLine();
        }

        public static IEnumerable<DateRange> SplitInToDays(DateRange range)
        {
            var ranges = new List<DateRange>();

            var tempRange = new DateRange() { Start = range.Start, End = range.End };

            while (tempRange.Start.Date != tempRange.End.Date)
            {
                var dateRange = new DateRange()
                {
                    Start = tempRange.Start,
                    End = tempRange.Start.Date.AddDays(1)
                };
                ranges.Add(dateRange);
                tempRange.Start = dateRange.End;
            }

            ranges.Add(tempRange);

            return ranges;
        }
    }

    public class DateRange
    {
        public DateTime Start { get; set; }
        public DateTime End { get; set; }

        public TimeSpan Duration => End - Start;
    }
}

它从传入的原始实例中创建一个临时范围实例。然后只要该范围的开始和结束日期不同,它就会循环。每个循环将起始时间作为新范围的开始,并在第二天的午夜结束。然后它将温度范围提前到刚刚创建的范围的开始和结束。一旦开始和结束都在同一天,它只会添加剩下的内容。

没有错误检查,因此它很容易爆炸,或者在给定错误输入值的情况下卡在循环中。我会给你做检查。

它为我生成以下输出:

  

8/5/2017 9:00:00 AM - 8/6/2017 12:00:00 AM - 15:00:00

     

8/6/2017 12:00:00 AM - 8/7/2017 12:00:00 AM - 1.00:00:00

     

8/7/2017 12:00:00 AM - 8/7/2017 4:00:00 PM - 16:00:00