0

在两个时间范围内检查出租设备的可用性的最佳算法是什么?

我有设备的时间范围和现有的租赁(开始和结束日期)以及“新”租赁的时间范围。

例子:

New rental: 18 April 2013 - 25 April 2013

在这种情况下,我想返回 false:

a) Existing rental: 20 April 2013 - 24 April 2013
b) Existing rental: 16 April 2013 - 24 April 2013
c) Existing rental: 20 April 2013 - 28 April 2013
d) Existing rental: 16 April 2013 - 28 April 2013

可能还有更多案例,但我认为我想要什么很清楚。

4

3 回答 3

2

好吧,大概你想检查任何现有的租金是否与新的租金相交。

首先,您需要确定“相交”的确切含义。鉴于您给出了日期值(而不是日期/时间值),我建议您的日期范围可能包含两端(例如 4 月 20 日 - 4 月 22 日包括 4 月 22 日,因此与 4 月 22 日 - 4 月 24 日相交)。

接下来,你想得到一个合适的表示 - 我有偏见,但我建议Noda Time因为它有“只是一个日期”而不是“一个日期和时间”的表示。然后,您可能想要添加类似DateInterval复合类型的内容。

第三,我强烈建议在纸上画出可能性。画两条线,一条用于现有租赁,一条用于新租赁,并计算出所有可能性。我怀疑你实际上想要的只是:

public sealed class DateInterval
{
    private readonly LocalDate start;
    private readonly LocalDate end;

    // TODO: Properties

    public DateInterval(LocalDate start, LocalDate end)
    {
        // TODO: Assert that end >= start, and that they use the same
        // calendar system
        this.start = start;
        this.end = end;
    }

    public bool IntersectsWith(DateInterval other)
    {
        // It intersects *unless* it's either completely before or completely
        // after *other*. There are other ways of representing this, but it's
        // the way that makes most intuitive sense to me.
        return !(this.end < other.start || this.start > other.end);
    }
}
于 2013-04-21T19:24:35.490 回答
1

我认为您需要的是一个好的数据结构或一些逻辑。希望下面的逻辑可以过滤掉所有重叠的时间范围。

 var overlappingIntervals = intervals
                    .Where(r => 
                        (r.Start <= toCheck.Start && r.End >= toCheck.End) //inside a timeframe
                    || (r.Start >= toCheck.Start && r.End <= toCheck.End) //other is inside our timeframe
                    || (r.Start >= toCheck.Start && r.End >= toCheck.End && r.Start <=toCheck.End) //end overlap
                    || (r.Start <= toCheck.Start && r.End <= toCheck.End && r.End >= toCheck.Start)// start overlap

                    ).ToList();

我还放置了 commnets 来检测情况。

class Program
    {
        static void Main(string[] args)
        {
            List<DateInterval> intervals = new List<DateInterval>();
            intervals.Add(new DateInterval(Convert.ToDateTime("26 April 2013"), Convert.ToDateTime("27 April 2013")));
            intervals.Add(new DateInterval(Convert.ToDateTime("16 April 2013"), Convert.ToDateTime("24 April 2013")));
            intervals.Add(new DateInterval(Convert.ToDateTime("20 April 2013"), Convert.ToDateTime("28 April 2013")));
            intervals.Add(new DateInterval(Convert.ToDateTime("16 April 2013"), Convert.ToDateTime("28 April 2013")));

            DateInterval toCheck = new DateInterval(Convert.ToDateTime("16 April 2013"),
                                                    Convert.ToDateTime("25 April 2013"));

            var overlappingIntervals = intervals
                .Where(r => 
                    (r.Start <= toCheck.Start && r.End >= toCheck.End) //inside a timeframe
                || (r.Start >= toCheck.Start && r.End <= toCheck.End) //other is inside our timeframe
                || (r.Start >= toCheck.Start && r.End >= toCheck.End && r.Start <=toCheck.End) //end overlap
                || (r.Start <= toCheck.Start && r.End <= toCheck.End && r.End >= toCheck.Start)// start overlap

                ).ToList();
            Console.Write(overlappingIntervals.Count);

        }
    }


    public class DateInterval
    {

        public DateInterval(DateTime Start, DateTime End)
        {
            this.Start = Start;
            this.End = End;
        }
        public DateTime Start { get; set; }
        public DateTime End { get; set; }
    }
于 2013-04-21T19:53:32.047 回答
0

您可以使用.NET 的时间周期库来检查时间框架的可用性:

// ----------------------------------------------------------------------
public void CheckAvailableTmeFrame()
{
  TimePeriodCollection periods = new TimePeriodCollection();
  periods.Add( new TimeRange( new DateTime( 2013, 4, 20 ), new DateTime( 2013, 4, 24 ) ) );
  periods.Add( new TimeRange( new DateTime( 2013, 4, 16 ), new DateTime( 2013, 4, 24 ) ) );
  periods.Add( new TimeRange( new DateTime( 2013, 4, 20 ), new DateTime( 2013, 4, 28 ) ) );
  periods.Add( new TimeRange( new DateTime( 2013, 4, 16 ), new DateTime( 2013, 4, 26 ) ) );

  // test period
  TimeRange test = new TimeRange( new DateTime( 2013, 4, 18 ), new DateTime( 2013, 4, 25 ) );

  // find the available 
  TimeGapCalculator<TimeRange> gapCalculator = new TimeGapCalculator<TimeRange>();
   ITimePeriodCollection gaps = gapCalculator.GetGaps( periods, test );

  Console.WriteLine( "Time frame {0}. Available: {1}", 
     test, gaps.Count == 1 && gaps[ 0 ].Equals( test ) );
} // CheckAvailableTmeFrame
于 2013-04-23T15:37:03.403 回答