假设我有两个时间范围
07.00.00 - 18.59.59
19.00.00 - 06.59.59
现在我有一个时间跨度范围,我们称之为持续时间。
public class Duration {
public TimeSpan StartingTime{get; set;}
public TimeSpan EndingTime{get; set;}
}
初始化为
StartingTime 05.00.00
EndingTime 06.00.00
我想生成一种方法,其中我在时间跨度范围列表中传递,以及一个新的Timespan,它将返回正确的时间范围。
我尝试修改Check if a date range is within a date range for TimeSpan,同时尝试将我的时间跨度范围转换为日期时间,但导致失败(不返回任何内容)。
我也尝试过
var fee = fees.Where(a=> parking.StartTime <= a.EndingTime && parking.EndTime >= a.StartingTime).First();
停车位是持续时间等级,费用将是一个时间范围列表。
我也看了c# check if a timespan range is between timespan range and how many hours,但这也没有导致工作解决方案。
我已经非常沮丧,无法想出解决方案。
编辑:以@NetMage为例,有一个案例,19.40 - 20.35会导致失败,我修复了另外一个条件。
var fee = fees
.First(r => (r.StartingTime <= r.EndingTime) ?
(r.StartingTime <= parking.StartTime && parking.StartTime <= r.EndingTime) :
(parking.StartTime <= r.EndingTime) ?
(r.StartingTime <= parking.StartTime + oneDay && parking.StartTime <= r.EndingTime)
: (r.StartingTime <= parking.StartTime + oneDay && parking.StartTime <= r.EndingTime + oneDay)
);
EDIT2 //
现在我仍然遇到检查endTime重叠的问题。尝试使用NetMage告诉的方法,但到目前为止没有什么
EDIT3 //
要检查结束部分,它将是
fees.First(r => (r.StartingTime <= r.EndingTime) ?
(r.EndingTime >= end && end >= r.StartingTime) :
(end >= r.StartingTime) ?
(r.EndingTime >= end + oneDay && end >= r.StartingTime) :
(r.EndingTime >= end + oneDay && end >= r.StartingTime + oneDay)
);
最后检查一下它是否重叠:
fees.First(r => r.StartingTime >= start && r.EndingTime <= end);
答案 0 :(得分:1)
假设您的时间范围列表是List<Duration>
,您可以这样查询:
var OneDay = new TimeSpan(24,0,0);
var startAns = ranges.First(r => {
var rEndingTime = (r.StartingTime > r.EndingTime) ? r.EndingTime + OneDay : r.EndingTime;
return (r.StartingTime <= parking.StartingTime && parking.StartingTime <= rEndingTime) ||
(r.StartingTime <= parking.StartingTime + OneDay && parking.StartingTime + OneDay <= rEndingTime);
});
var endAns = ranges.First(r => {
var rEndingTime = (r.StartingTime > r.EndingTime) ? r.EndingTime + OneDay : r.EndingTime;
return (r.StartingTime <= parking.EndingTime && parking.EndingTime <= rEndingTime) ||
(r.StartingTime <= parking.EndingTime + OneDay && parking.EndingTime + OneDay <= rEndingTime);
});
我将上面的原始(基于概念)Let
的答案替换为上述答案,同时使用了OP使用的漂亮First
变体。
var ans = ranges.Select(r => new { r, r.StartingTime, EndingTime = (r.StartingTime > r.EndingTime ? r.EndingTime + OneDay : r.EndingTime)})
.Where(r => (r.StartingTime <= parking.StartingTime && parking.StartingTime <= r.EndingTime) ||
(r.StartingTime <= parking.StartingTime+OneDay && parking.StartingTime+OneDay <= r.EndingTime))
.Select(r => r.r).First();
答案 1 :(得分:0)
已更新,可解决期间翻转至第二天的问题
使用TimeSpan
非常简洁,但是如果一个句点滚动到第二天,这将使查询变得非常复杂和笨拙。
通过将涵盖两天的期间分为两个期间,可以轻松解决此问题:
00.00.00 - 06.59.59 //off peak 1
07.00.00 - 18.59.59 //peak
19.00.00 - 23.59.59 //off peak 2
在您的示例中,您有两种可能需要处理的案例:
.First()
要获得更准确的答案,您需要指定所需的行为。关于这些可能适合的机会,这里有两种可能性:
此查询将返回停车启动
中的费用期限: var fee = fees.Where(period =>
parking.StartTime >= period.StartingTime && parking.StartTime <= period.EndingTime).First();
此查询将返回停车结束
中的费用期限: var fee = fees.Where(period =>
parking.EndTime >= period.StartingTime && parking.EndTime <= period.EndingTime).First();