假设我有3个时间范围:
07:00 - 18:00
18:00 - 23:00
23:00 - 07:00
和代码:
public class TimeShift
{
public TimeSpan Start { get; set; }
public TimeSpan End { get; set; }
}
List<TimeShift> shifts = new List<TimeShift>();
如何检查列表中的每一项是否都在上述3个范围和多少小时之间?
例如,一个TimeShift
,其中:
Start: 07:00
End: 23:30
那就意味着16.5个小时。
对于上面的示例:
Range 1: 11 hours
Range 2: 5 hours
Range 3: 0.5 hours
发布于 2016-12-02 00:28:09
下面是一个包含测试的解决方案:
计算
public class TimeSpacCalculator
{
public static TimeSpan GetTimeSpanIntersect(TimeShift input, TimeSpan start, TimeSpan end)
{
// Loopsback input from 23:59 - 00:00
if (input.Start > input.End)
return GetTimeSpanIntersect(new TimeShift(input.Start, TimeSpan.FromHours(24)), start, end) +
GetTimeSpanIntersect(new TimeShift(TimeSpan.FromHours(0), input.End), start, end);
// Loopsback Shift from 23:59 - 00:00
if (start > end)
return GetTimeSpanIntersect(input, new TimeSpan(), end) +
GetTimeSpanIntersect(input, start, TimeSpan.FromHours(24));
if (input.End < start)
return new TimeSpan();
if (input.Start > end)
return new TimeSpan();
var actualStart = input.Start < start
? start
: input.Start;
var actualEnd = input.End > end
? end
: input.End;
return actualEnd - actualStart;
}
}
类
public class TimeRange : TimeShift
{
public TimeRange(string name, TimeSpan start, TimeSpan end) : base(start, end)
{
Name = name;
}
public string Name { get; set; }
}
public class TimeShift
{
public TimeShift(TimeSpan start, TimeSpan end)
{
Start = start;
End = end;
}
public TimeSpan Start { get; set; }
public TimeSpan End { get; set; }
}
测试
[TestFixture]
internal class TimShiftTests
{
[Test]
[TestCase(7, 23.5, 11, 5, 0.5)]
[TestCase(22, 7.5, 0.5, 1, 8)]
public void Test(double inputStartHours, double inputEndHours, double expectedRange1Hours, double expectedRange2Hours, double expectedRange3Hours )
{
var input = new TimeShift(TimeSpan.FromHours(inputStartHours), TimeSpan.FromHours(inputEndHours));
var ranges = new List<TimeRange>
{
new TimeRange("Range1", TimeSpan.FromHours(7), TimeSpan.FromHours(18)),
new TimeRange("Range2", TimeSpan.FromHours(18), TimeSpan.FromHours(23)),
new TimeRange("Range3", TimeSpan.FromHours(23), TimeSpan.FromHours(7))
};
var result = new Dictionary<string, TimeSpan>();
foreach (var range in ranges)
{
var time = TimeSpacCalculator.GetTimeSpanIntersect(input, range.Start, range.End);
result.Add(range.Name, time);
Console.WriteLine($"{range.Name}: " + time.TotalHours);
}
result["Range1"].Should().Be(TimeSpan.FromHours(expectedRange1Hours));
result["Range2"].Should().Be(TimeSpan.FromHours(expectedRange2Hours));
result["Range3"].Should().Be(TimeSpan.FromHours(expectedRange3Hours));
}
发布于 2016-12-02 00:07:56
您使用了错误的类型。Start
和End
应该是DateTime
,而不是TimeSpan
。End.Subtract(Start)
将提供一个TimeSpan
作为其结果。TimeSpan
类型具有将提供总小时数、分钟数等的属性。
TimeSpan属性(https://msdn.microsoft.com/en-us/library/system.timespan_properties(v=vs.110%29.aspx)
发布于 2016-12-02 00:08:19
我建议在您的类中添加一个表示start和end之间实际差异的方法。例如,将其称为timespan TimeDiff。您需要包含一条if语句,以确认TimeLater小于TimeEnd且TimeEarlier大于TimeStart。然后是'TimeDiff = TimeLater - TimeEarlier‘。
TimeLater是提供的范围的末尾。TimeEarlier是提供的范围的开始。
如果你想计算从TimeEnd到TimeStart的时间跨度,你只需要检查TimeEarlier是否大于TimeLater,并且有逻辑来计算差值。它将沿着TimeDiff = (TimeEnd - TimeEarlier) + (TimeLater - TimeEnd)的方向进行。
要完成timespan减法,请在所有timespan中使用.Subtract()
https://stackoverflow.com/questions/40922409
复制