如何判断一个时间跨度范围是否在哪个时间跨度范围之间
How to figure out wether a range of timespan is between which range of timespan
假设我有两个时间跨度范围
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
我想生成一个方法,在其中传递时间跨度范围列表和一个新的时间跨度,它将 return 给我一个正确的时间跨度范围。
我曾尝试为 TimeSpan 修改 Check if a date range is within a date range,还尝试将我的时间跨度范围转换为日期时间,但结果失败(return 什么都没有)。
我也试过
var fee = fees.Where(a=> parking.StartTime <= a.EndingTime && parking.EndTime >= a.StartingTime).First();
其中停车是持续时间 class,费用是时间跨度范围的列表。
我也看过 但这也没有产生有效的解决方案。
我已经很沮丧了,想不出解决办法。
编辑:以@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);
已更新以解决月经顺延至第二天的问题
为此目的使用 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()
要获得更准确的答案,您需要指定您需要的行为应该是什么。如果这些可能合适,这里有两种可能性:
此查询将return停车开始的收费期:
var fee = fees.Where(period =>
parking.StartTime >= period.StartingTime && parking.StartTime <= period.EndingTime).First();
此查询将 return 停车结束 的费用期限:
var fee = fees.Where(period =>
parking.EndTime >= period.StartingTime && parking.EndTime <= period.EndingTime).First();
假设您的时间范围列表是 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();
假设我有两个时间跨度范围
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
我想生成一个方法,在其中传递时间跨度范围列表和一个新的时间跨度,它将 return 给我一个正确的时间跨度范围。
我曾尝试为 TimeSpan 修改 Check if a date range is within a date range,还尝试将我的时间跨度范围转换为日期时间,但结果失败(return 什么都没有)。
我也试过
var fee = fees.Where(a=> parking.StartTime <= a.EndingTime && parking.EndTime >= a.StartingTime).First();
其中停车是持续时间 class,费用是时间跨度范围的列表。
我也看过
我已经很沮丧了,想不出解决办法。
编辑:以@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);
已更新以解决月经顺延至第二天的问题
为此目的使用 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()
要获得更准确的答案,您需要指定您需要的行为应该是什么。如果这些可能合适,这里有两种可能性:
此查询将return停车开始的收费期:
var fee = fees.Where(period =>
parking.StartTime >= period.StartingTime && parking.StartTime <= period.EndingTime).First();
此查询将 return 停车结束 的费用期限:
var fee = fees.Where(period =>
parking.EndTime >= period.StartingTime && parking.EndTime <= period.EndingTime).First();
假设您的时间范围列表是 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();