【问题标题】:How to figure out wether a range of timespan is between which range of timespan如何确定时间跨度范围是否在哪个时间跨度范围之间
【发布时间】:2017-09-11 18:39:16
【问题描述】:

假设我有两个时间跨度范围

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,还尝试将我的时间跨度范围转换为日期时间,但结果失败(不返回任何内容)。

我也试过了

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);

【问题讨论】:

  • 你可以发布你的模型来收费吗?
  • 您的停车变量是否实现了 Duration 模型?
  • 也对您正在寻找的输出类型感到困惑。是超出或指定范围的任何费用,还是指定范围内的任何费用?
  • 嗯,你为什么在 TimeSpan 而不是 DateTimes 期间实现持续时间?更好的是,为什么要有一个持续时间类,而不是只使用一个 TimeSpan?
  • 你能举一个输入和预期输出的例子吗?

标签: c# linq timespan


【解决方案1】:

假设您的时间范围列表是List&lt;Duration&gt;,您可以这样查询:

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();

【讨论】:

  • Hello @NetMage 这是一个很好的解决方案,但如果时间是例如 19:40 – 20:35 ,这将失败。这是因为条件停车.StartTime
  • 如果可能的话,你能帮我想想结束时间重叠的类似问题吗?
  • 你是对的,优化版本并非在所有情况下都有效。我添加了parking.EndingTime 的表达式。
【解决方案2】:

已更新以解决将期间翻转到第二天的问题

为此目的使用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() 而崩溃

要获得更准确的答案,您需要指定所需的行为应该是什么。如果这些可能是合适的,这里有两种可能性:

此查询将返回停车开始的费用周期:

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();

【讨论】:

  • 开始部分正是我想要的。干杯。编辑//第二次看。它仍然失败,因为在这种情况下,它应该落入 19.00.00 - 06.59.59 的范围内。但是,例如,起始时间 05.00.00 不大于期间起始时间 (19.00.00),这仍然会返回错误。
  • @EgertAia 你的范围让我很困惑。你有它从 19 开始到 7 结束。你的开始时间怎么会大于你的结束时间?这是因为它进入第二天吗?
  • @EgertAia 我明白了 - 用我的建议更新了答案以解决这个问题。可以通过查询来完成,但我认为这是一个更好的解决方案。
猜你喜欢
  • 1970-01-01
  • 2012-08-25
  • 1970-01-01
  • 2012-10-22
  • 2011-09-08
  • 2016-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多