Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 两个列表中的日期时间不重叠_C#_.net_Linq - Fatal编程技术网

C# 两个列表中的日期时间不重叠

C# 两个列表中的日期时间不重叠,c#,.net,linq,C#,.net,Linq,我正在做一个个人项目,只返回我拥有的可用插槽。 我有两个列表,一个包含所有可能的日期时间段,另一个包含所有的块日期时间 现在我有下面的代码,但是正在返回重叠的记录(这与我想要的相反) 那么,我做错了什么,最好的方法是什么 (我进行了搜索,没有找到任何与非重叠日期时间相关的内容) 结果应该是这样的: 2018-09-01 05:00:00 2018-09-02 01:30:00 类日期跨度 { 公共日期时间开始日期; 公共日期时间结束日期 public DateSpan(DateTime sta

我正在做一个个人项目,只返回我拥有的可用插槽。 我有两个列表,一个包含所有可能的日期时间段,另一个包含所有的块日期时间

现在我有下面的代码,但是正在返回重叠的记录(这与我想要的相反)

那么,我做错了什么,最好的方法是什么

(我进行了搜索,没有找到任何与非重叠日期时间相关的内容)

结果应该是这样的:

  • 2018-09-01 05:00:00
  • 2018-09-02 01:30:00

    类日期跨度 { 公共日期时间开始日期; 公共日期时间结束日期

    public DateSpan(DateTime start, DateTime end)
    {
        StartDate = start;
        EndDate = end;
    }
    
    public DateSpan(DateTime start, int duration)
    {
        StartDate = start;
        EndDate = start.AddHours(duration);
    }
    
    
    public static void Main(string[] args)
    {
        var AvailableHours = new System.Collections.Generic.List<DateSpan>();
        AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 1, 5, 0, 0), 2));
        AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 2, 4, 0, 0), 2));
        AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 2, 5, 0, 0), 2));
        AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 2, 1, 30, 0), 2));
        AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 4, 5, 0, 0), 2));
    
        var BlockTimes = new System.Collections.Generic.List<DateSpan>();
        BlockTimes.Add(new DateSpan(new DateTime(2018, 9, 1, 10, 0, 0), 2));
        BlockTimes.Add(new DateSpan(new DateTime(2018, 9, 2, 5, 0, 0), 2));
        BlockTimes.Add(new DateSpan(new DateTime(2018, 9, 3, 5, 0, 0), 2));
        BlockTimes.Add(new DateSpan(new DateTime(2018, 9, 4, 4, 0, 0), 2));
    
        var e = AvailableHours.SelectMany((DateSpan x) =>
        {
            var result = new List<DateSpan>();
            foreach (var o in BlockTimes.Where(y => x.StartDate < y.StartDate && y.StartDate < x.EndDate).ToList())
            {
                result.Add(new DateSpan(new DateTime(Math.Max(x.StartDate.Ticks, o.StartDate.Ticks)), new DateTime(Math.Min(x.EndDate.Ticks, o.EndDate.Ticks))));
            }
            return result;
        });
    }
    
    public DateSpan(日期时间开始,日期时间结束)
    {
    开始日期=开始;
    结束日期=结束;
    }
    公共日期跨度(日期时间开始,整数持续时间)
    {
    开始日期=开始;
    EndDate=开始时长(持续时间);
    }
    公共静态void Main(字符串[]args)
    {
    var AvailableHours=new System.Collections.Generic.List();
    添加(新的日期跨度(新的日期时间(2018,9,1,5,0,0,2));
    添加(新的日期跨度(新的日期时间(2018,9,2,4,0,0,2));
    添加(新的日期跨度(新的日期时间(2018,9,2,5,0,0,2));
    添加(新的日期跨度(新的日期时间(2018,9,2,1,30,0,2));
    添加(新的日期跨度(新的日期时间(2018,9,4,5,0,0,2));
    var BlockTimes=new System.Collections.Generic.List();
    添加(新的日期跨度(新的日期时间(2018,9,1,10,0,0,2));
    添加(新的日期跨度(新的日期时间(2018,9,2,5,0,0,2));
    添加(新的日期跨度(新的日期时间(2018,9,3,5,0,0,2));
    添加(新的日期跨度(新的日期时间(2018,9,4,4,0,0,2));
    变量e=可用小时数。选择多个((日期跨度x)=>
    {
    var result=新列表();
    foreach(BlockTimes.Where(y=>x.StartDate
    }


根据对您问题的澄清,这似乎起到了作用。它使用foreach循环而不是直接Linq,但对我来说,这使代码更可读,解决方案更直观:

private List<DateSpan> GetNonOverlappingTimes()
{
    var AvailableHours = new System.Collections.Generic.List<DateSpan>();
    AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 1, 5, 0, 0), 2));
    AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 2, 4, 0, 0), 2));
    AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 2, 5, 0, 0), 2));
    AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 2, 1, 30, 0), 2));
    AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 4, 5, 0, 0), 2));

    var BlockTimes = new System.Collections.Generic.List<DateSpan>();
    BlockTimes.Add(new DateSpan(new DateTime(2018, 9, 1, 10, 0, 0), 2));
    BlockTimes.Add(new DateSpan(new DateTime(2018, 9, 2, 5, 0, 0), 2));
    BlockTimes.Add(new DateSpan(new DateTime(2018, 9, 3, 5, 0, 0), 2));
    BlockTimes.Add(new DateSpan(new DateTime(2018, 9, 4, 4, 0, 0), 2));

    var availableTimes = new List<DateSpan>();
    foreach (var avail in AvailableHours)
    {
        // check if there are any block times where the start date or end date is between the start date and end date of the available time
        bool isConflict = BlockTimes.Exists(bt => (bt.StartDate >= avail.StartDate && bt.StartDate < avail.EndDate) || (bt.EndDate > avail.StartDate && bt.EndDate <= avail.EndDate));

        if (!isConflict)
            availableTimes.Add(avail);
    }
    return availableTimes;
}
private List GetNonOverlappingTimes()
{
var AvailableHours=new System.Collections.Generic.List();
添加(新的日期跨度(新的日期时间(2018,9,1,5,0,0,2));
添加(新的日期跨度(新的日期时间(2018,9,2,4,0,0,2));
添加(新的日期跨度(新的日期时间(2018,9,2,5,0,0,2));
添加(新的日期跨度(新的日期时间(2018,9,2,1,30,0,2));
添加(新的日期跨度(新的日期时间(2018,9,4,5,0,0,2));
var BlockTimes=new System.Collections.Generic.List();
添加(新的日期跨度(新的日期时间(2018,9,1,10,0,0,2));
添加(新的日期跨度(新的日期时间(2018,9,2,5,0,0,2));
添加(新的日期跨度(新的日期时间(2018,9,3,5,0,0,2));
添加(新的日期跨度(新的日期时间(2018,9,4,4,0,0,2));
var availableTimes=新列表();
foreach(可用小时内的var avail)
{
//检查是否存在开始日期或结束日期介于可用时间的开始日期和结束日期之间的阻塞时间

bool isConflict=BlockTimes.Exists(bt=>(bt.StartDate>=avail.StartDate和&bt.StartDateavail.StartDate和&bt.EndDate在
DateSpan
类中定义一个方法,该方法将知道如何确定两个日期跨度是否相交:

public bool Intersect(DateSpan other)
{
    return (this.StartDate >= other.StartDate && this.StartDate <= other.EndDate) ||
           (this.EndDate >= other.StartDate && this.EndDate <= other.EndDate);
}
public bool Intersect(日期跨度其他)
{
return(this.StartDate>=other.StartDate&&this.StartDate=other.StartDate&&this.EndDate BlockTimes.All(y=>!x.Intersect(y)).ToList();
}

那么,您希望得到什么结果?有哪些可用插槽?例如,如果您有一个从下午2点到晚上7点的可用插槽和一个从下午3点到下午4点的阻塞插槽,它是否应该返回两个插槽:下午2点到3点和下午4点到7点?@YeldarKurmangaliyev,结果应该是2018-09-01 05:00:00 2018-09-02 01:30:00@YeldarKurmangaliyev在您的示例中,应该返回零个插槽。在这种情况下,我们应该返回零个插槽。我只想返回块列表中不重叠的插槽。不知道这是否使问题变得简单:)@piort-查看修改后的答案-我一开始不明白你想做什么。你给我的是一个额外的插槽,这是错误的。插槽2018-09-02 05:00:00处于阻塞时间。我想我必须将其更改为=对吗?@piort用>=和更新了解决方案
private List<DateSpan> GetNonOverlappingTimes()
{
    var AvailableHours = new System.Collections.Generic.List<DateSpan>();
    AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 1, 5, 0, 0), 2));
    AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 2, 4, 0, 0), 2));
    AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 2, 5, 0, 0), 2));
    AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 2, 1, 30, 0), 2));
    AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 4, 5, 0, 0), 2));

    var BlockTimes = new System.Collections.Generic.List<DateSpan>();
    BlockTimes.Add(new DateSpan(new DateTime(2018, 9, 1, 10, 0, 0), 2));
    BlockTimes.Add(new DateSpan(new DateTime(2018, 9, 2, 5, 0, 0), 2));
    BlockTimes.Add(new DateSpan(new DateTime(2018, 9, 3, 5, 0, 0), 2));
    BlockTimes.Add(new DateSpan(new DateTime(2018, 9, 4, 4, 0, 0), 2));

    return AvailableHours.Where(x => BlockTimes.All(y => !x.Intersect(y))).ToList();
}