我有一个以开头和结尾为界的日期范围,我希望得到一个范围列表,将原始范围分成各个日期的范围。因此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。有没有办法让干净的短代码来实现这个目标?
答案 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