Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.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# - Fatal编程技术网

C# 检查日期范围是否在日期范围内

C# 检查日期范围是否在日期范围内,c#,C#,我有以下课程: public class Membership { public DateTime StartDate { get; set; } public DateTime? EndDate { get; set; } // If null then it lasts forever } 我需要确保添加到以下列表时,新项目不会与现有项目的日期重叠: var membership = new List<Membership> { new Membersh

我有以下课程:

public class Membership
{
    public DateTime StartDate { get; set; }
    public DateTime? EndDate { get; set; } // If null then it lasts forever
}
我需要确保添加到以下列表时,新项目不会与现有项目的日期重叠:

var membership = new List<Membership>
{
    new Membership { StartDate = DateTime.UtcNow.AddDays(-10), EndDate = DateTime.UtcNow.AddDays(-5) },
    new Membership { StartDate = DateTime.UtcNow.AddDays(-5), EndDate = null }
};

我原以为这很简单,但到目前为止,我的尝试都是错误的,我开始困惑自己,希望有人做了类似的事情,他们可以分享。谢谢

像这样的情况应该会奏效:

newItem.StartDate <= range.EndDate && newItem.EndDate.HasValue && newItem.EndDate >= range.StartDate
newItem.StartDate=range.StartDate

如果我理解正确-您想确保日期范围2不在日期范围1内吗

例如:

startDate1 = 01/01/2011

endDate1 = 01/02/2011

这应该是一个简单的例子:

if ((startDate2 >= startDate1 &&  startDate2 <= endDate1) || 
    (endDate2   >= startDate1 && endDate2   <= endDate1))

如果((startDate2>=startDate1&&startDate2=startDate1&&endDate2)基本上,一个日期范围与另一个日期范围重叠,如果其任何结尾在另一个范围内,则反之亦然

static bool AllowedToAdd(List<Membership> membershipList, Membership newItem)
{
    return !membershipList.Any(m =>
        (m.StartDate < newItem.StartDate &&
         newItem.StartDate < (m.EndDate ?? DateTime.MaxValue))
        ||
        (m.StartDate < (newItem.EndDate ?? DateTime.MaxValue) &&
         (newItem.EndDate ?? DateTime.MaxValue) <= (m.EndDate ?? DateTime.MaxValue))
        ||
        (newItem.StartDate < m.StartDate &&
         m.StartDate < (newItem.EndDate ?? DateTime.MaxValue))
        ||
        (newItem.StartDate < (m.EndDate ?? DateTime.MaxValue) &&
         (m.EndDate ?? DateTime.MaxValue) <= (newItem.EndDate ?? DateTime.MaxValue))
        );
}
下面是一个使用
集合的解决方案(缺少
null
参数验证,以及
Membership
中的验证,即
EndDate>StartDate
):

公共类成员资格
{
公共日期时间起始日期{get;set;}
public DateTime?EndDate{get;set;}//如果为空,则它将永远持续
私有DateTime NullSafeEndDate{get{return EndDate??DateTime.MaxValue;}}
private bool IsFullyAfter(其他会员资格)
{
返回StartDate>other.NullSafeEndDate;
}
公共布尔重叠(其他成员)
{
return!IsFullyAfter(其他)和&!other.IsFullyAfter(此);
}
}
公共类成员身份集合:集合
{
受保护的重写void插入项(int索引,成员资格成员)
{
if(加拿大(成员))
基本插入项(索引,成员);
else抛出新的ArgumentException(“范围不能重叠”);
}
公共bool CanAdd(会员)
{
return!this.Any(member.Overlaps);
}
}

< /代码> 如果你没有不同的排序标准,那么先按顺序维护你的列表。因为没有以前添加的对象被允许重叠,所以一旦你知道你要添加一个新对象的点,你只需要比较两边的单个对象就可以确定新的对象。你也只需要考虑。“较早”对象的结束日期是否与“较晚”对象的开始日期重叠,因为此顺序使得重叠的其他可能性无关

因此,除了简化检测重叠的问题外,我们还可以将复杂性从O(n)of降低到O(logn),而不是与所有现有项进行比较,而是与通过O(logn)搜索找到的0-2进行比较

私有类成员身份比较程序:IComparer
{
公共整数比较(成员x、成员y)
{
返回x.StartDate.CompareTo(y.StartDate);
}
}
私有静态bool AddMembership(列表lst、成员ms)
{
int bsr=lst.BinarySearch(ms,newmembershipComparer());
if(bsr>=0)//现有对象具有完全相同的起始日期,因此重叠
//(您可能或可能不想考虑零秒日期范围的情况)
返回false;
int idx=~bsr;//要在if处插入的索引不匹配。
如果(idx!=0)
{
成员资格prev=lst[idx-1];
//如果允许包含范围(前一个端点完全相同
//作为下一个开始,将此行更改为:
//如果(!prev.EndDate.HasValue | | prev.EndDate>ms.StartDate)
如果(prev.EndDate??DateTime.MaxValue>=ms.StartDate)
返回false;
}
如果(idx!=1次计数)
{
下一个成员=lst[idx];
//如果允许包含范围,请更改为:
//如果(!ms.EndDate.HasValue | | ms.EndDate>next.StartDate)
如果(ms.EndDate??DateTime.MaxValue>=next.StartDate)
返回false;
}
第一次插入(idx,ms);
返回true;
}
如果无法添加到列表中,则上述返回
false
。如果更适合引发异常,则这是一个简单的修改。

public bool在提供的时间范围内不提供ReadyExistin(int RetailerId、DateTime ValidFrom、DateTime ValidTo)
public bool DoesAnOfferAlreadyExistWithinTheTimeframeProvided(int RetailerId, DateTime ValidFrom, DateTime ValidTo)
        {
            bool result = true;

            try
            {
                // Obtain the current list of coupons associated to the retailer.
                List<RetailerCoupon> retailerCoupons = PayPalInStore.Data.RetailerCoupon.Find(x => x.RetailerId == RetailerId).ToList();

                // Loop through each coupon and see if the timeframe provided in the NEW coupon doesnt fall between any EZISTING coupon.
                if (retailerCoupons != null)
                {
                    foreach (RetailerCoupon coupon in retailerCoupons)
                    {
                        DateTime retailerCouponValidFrom = coupon.DateValidFrom;
                        DateTime retailerCouponValidTo = coupon.DateExpires;

                        if ((ValidFrom <= retailerCouponValidFrom && ValidTo <= retailerCouponValidFrom) || (ValidFrom >= retailerCouponValidTo && ValidTo >= retailerCouponValidTo))
                        {
                            return false;
                        }
                    }
                }

                return result;
            }
        catch (Exception ex)
        {
            this.errorManager.LogError("DoesAnOfferAlreadyExistWithinTheTimeframeProvided failed", ex);
            return result;
        }
    }
{ 布尔结果=真; 尝试 { //获取与零售商关联的优惠券的当前列表。 List retailerCoupons=PayPalInStore.Data.RetailerCoupon.Find(x=>x.RetailerId==RetailerId.ToList(); //循环浏览每一张优惠券,看看新优惠券中提供的时间范围是否在任何现有优惠券之间。 if(零售组!=null) { foreach(零售团体中的零售团体优惠券) { DateTime RetailerGrouponValidFrom=优惠券。DateValidFrom; DateTime RetailerGrouponValidTo=优惠券。DateExpires; 如果((ValidFrom=RetailerGrouponValidTo)) { 返回false; } } } 返回结果; } 捕获(例外情况除外) { this.errorManager.LogError(“DoesanOfferReadyExistwithinthetimeframesfiled failed”,ex); 返回结果; } }
有点晚了,但我在答案/评论中找不到这种模式

    if (startDate1 <= endDate2 && startDate2 <= endDate1)
    {
     // Overlaps.
    }

if(startDate1我想出了以下方法来检查日期是否重叠,这可能不是最有效的方法,但我希望这能有所帮助

public static bool DateRangesOverlap(DateTime startDateA, DateTime endDateA, DateTime startDateB, DateTime endDateB)
{
    var allDatesA = new List<DateTime>();
    var allDatesB = new List<DateTime>();

    for (DateTime date = startDateA; date <= endDateA; date = date.AddDays(1))
    {
        allDatesA.Add(date);
    }

    for (DateTime date = startDateB; date <= endDateB; date = date.AddDays(1))
    {
        allDatesB.Add(date);
    }

    var isInRange = false;
    foreach (var date in allDatesA)
    {
        var existsInAllDatesB = allDatesB.Any(x => x == date);
        if (existsInAllDatesB)
        {
            isInRange = true;
            break;
        }
    }

    return isInRange;
}
public static bool DateRangesOverlap(DateTime startDateA、DateTime endDateA、DateTime startDateB、DateTime endDateB)
{
var allDatesA=新列表();
var allDatesB=新列表();

对于(DateTime date=startDateA;date),您还应该检查空值。感谢所有人的回复,但我更喜欢这个,因为它是最容易理解的lol。这是一个非常符合逻辑的天才解决方案。Thnx@Joachim VR
public class Membership
{
    public DateTime StartDate { get; set; }
    public DateTime? EndDate { get; set; } // If null then it lasts forever

    private DateTime NullSafeEndDate { get { return EndDate ?? DateTime.MaxValue; } }  

    private bool IsFullyAfter(Membership other)
    {
       return StartDate > other.NullSafeEndDate;
    }

    public bool Overlaps(Membership other)
    {
      return !IsFullyAfter(other) && !other.IsFullyAfter(this);
    }
}


public class MembershipCollection : Collection<Membership>
{
   protected override void InsertItem(int index, Membership member)
   {
       if(CanAdd(member))
          base.InsertItem(index, member);
       else throw new ArgumentException("Ranges cannot overlap.");
   }

   public bool CanAdd(Membership member) 
   {
       return !this.Any(member.Overlaps);
   }
}
private class MembershipComparer : IComparer<Membership>
{
  public int Compare(Membership x, Membership y)
  {
    return x.StartDate.CompareTo(y.StartDate);
  }
}
private static bool AddMembership(List<Membership> lst, Membership ms)
{
  int bsr = lst.BinarySearch(ms, new MembershipComparer());
  if(bsr >= 0)    //existing object has precisely the same StartDate and hence overlaps
                  //(you may or may not want to consider the case of a zero-second date range)
    return false;
  int idx = ~bsr; //index to insert at if doesn't match already.
  if(idx != 0)
  {
    Membership prev = lst[idx - 1];
    // if inclusive ranges is allowed (previous end precisely the same
    // as next start, change this line to:
    // if(!prev.EndDate.HasValue || prev.EndDate > ms.StartDate)
    if(prev.EndDate ?? DateTime.MaxValue >= ms.StartDate)
      return false;
  }
  if(idx != lst.Count)
  {
    Membership next = lst[idx];
    // if inclusive range is allowed, change to:
    // if(!ms.EndDate.HasValue || ms.EndDate > next.StartDate)
    if(ms.EndDate ?? DateTime.MaxValue >= next.StartDate)
      return false;
  }
  lst.Insert(idx, ms);
  return true;
}
public bool DoesAnOfferAlreadyExistWithinTheTimeframeProvided(int RetailerId, DateTime ValidFrom, DateTime ValidTo)
        {
            bool result = true;

            try
            {
                // Obtain the current list of coupons associated to the retailer.
                List<RetailerCoupon> retailerCoupons = PayPalInStore.Data.RetailerCoupon.Find(x => x.RetailerId == RetailerId).ToList();

                // Loop through each coupon and see if the timeframe provided in the NEW coupon doesnt fall between any EZISTING coupon.
                if (retailerCoupons != null)
                {
                    foreach (RetailerCoupon coupon in retailerCoupons)
                    {
                        DateTime retailerCouponValidFrom = coupon.DateValidFrom;
                        DateTime retailerCouponValidTo = coupon.DateExpires;

                        if ((ValidFrom <= retailerCouponValidFrom && ValidTo <= retailerCouponValidFrom) || (ValidFrom >= retailerCouponValidTo && ValidTo >= retailerCouponValidTo))
                        {
                            return false;
                        }
                    }
                }

                return result;
            }
        catch (Exception ex)
        {
            this.errorManager.LogError("DoesAnOfferAlreadyExistWithinTheTimeframeProvided failed", ex);
            return result;
        }
    }
    if (startDate1 <= endDate2 && startDate2 <= endDate1)
    {
     // Overlaps.
    }
public static bool DateRangesOverlap(DateTime startDateA, DateTime endDateA, DateTime startDateB, DateTime endDateB)
{
    var allDatesA = new List<DateTime>();
    var allDatesB = new List<DateTime>();

    for (DateTime date = startDateA; date <= endDateA; date = date.AddDays(1))
    {
        allDatesA.Add(date);
    }

    for (DateTime date = startDateB; date <= endDateB; date = date.AddDays(1))
    {
        allDatesB.Add(date);
    }

    var isInRange = false;
    foreach (var date in allDatesA)
    {
        var existsInAllDatesB = allDatesB.Any(x => x == date);
        if (existsInAllDatesB)
        {
            isInRange = true;
            break;
        }
    }

    return isInRange;
}