如何判断一个时间跨度范围是否在哪个时间跨度范围之间

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

在您的示例中,您有两种可能的情况需要处理:

  1. 停车时长完全在一个费用周期内 - 由您的查询处理。
  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();