// Takes a list and returns all records that have overlapping time ranges.public static IEnumerable<T> GetOverlappedTimes<T>(IEnumerable<T> list, Func<T, bool> filter, Func<T,DateTime> start, Func<T, DateTime> end){// Selects all records that match filter() on left side and returns all records on right side that overlap.var overlap = from t1 in listwhere filter(t1)from t2 in listwhere !object.Equals(t1, t2) // Don't match the same record on right side.let in1 = start(t1)let out1 = end(t1)let in2 = start(t2)let out2 = end(t2)where in1 <= out2 && out1 >= in2let totover = GetMins(in1, out1, in2, out2)select t2;
return overlap;}
public static void TestOverlap(){var tl1 = new TempTimeEntry() { ID = 1, Name = "Bill", In = "1/1/08 1:00pm".ToDate(), Out = "1/1/08 4:00pm".ToDate() };var tl2 = new TempTimeEntry() { ID = 2, Name = "John", In = "1/1/08 5:00pm".ToDate(), Out = "1/1/08 6:00pm".ToDate() };var tl3 = new TempTimeEntry() { ID = 3, Name = "Lisa", In = "1/1/08 7:00pm".ToDate(), Out = "1/1/08 9:00pm".ToDate() };var tl4 = new TempTimeEntry() { ID = 4, Name = "Joe", In = "1/1/08 3:00pm".ToDate(), Out = "1/1/08 8:00pm".ToDate() };var tl5 = new TempTimeEntry() { ID = 1, Name = "Bill", In = "1/1/08 8:01pm".ToDate(), Out = "1/1/08 8:00pm".ToDate() };var list = new List<TempTimeEntry>() { tl1, tl2, tl3, tl4, tl5 };var overlap = GetOverlappedTimes(list, (TempTimeEntry t1)=>t1.ID==1, (TempTimeEntry tIn) => tIn.In, (TempTimeEntry tOut) => tOut.Out);
Console.WriteLine("\nRecords overlap:");foreach (var tl in overlap)Console.WriteLine("Name:{0} T1In:{1} T1Out:{2}", tl.Name, tl.In, tl.Out);Console.WriteLine("Done");
/* Output:Records overlap:Name:Joe T1In:1/1/2008 3:00:00 PM T1Out:1/1/2008 8:00:00 PMName:Lisa T1In:1/1/2008 7:00:00 PM T1Out:1/1/2008 9:00:00 PMDone*/}
class InclusiveRange:"""InclusiveRange class to represent a lower and upper bound."""
def __init__(self, start, end):"""Initialisation, ensures start <= end.Args:start: The start of the range.end: The end of the range."""self.start = min(start, end)self.end = max(start, end)
def __repr__(self):"""Return representation for f-string."""return f"({self.start}, {self.end})"
def overlaps(self, other):"""True if range overlaps with another.Args:other: The other InclusiveRange to check against."""
# Very limited recursion to ensure start of first range# isn't after start of second.
if self.start > other.start:return other.overlaps(self)
# Greatly simplified check for overlap.
return other.start <= self.end
然后是一个测试用例处理程序,允许我们很好地呈现单一测试用例的结果:
def test_case(range1, range2):"""Single test case checker."""
# Get low and high value for "graphic" output.
low = min(range1.start, range2.start)high = max(range1.end, range2.end)
# Output ranges and graphic.
print(f"r1={range1} r2={range2}: ", end="")for val in range(low, high + 1):is_in_first = range1.start <= val <= range1.endis_in_second = range2.start <= val <= range2.end
if is_in_first and is_in_second:print("|", end="")elif is_in_first:print("'", end="")elif is_in_second:print(",", end="")else:print(" ", end="")
# Finally, output result of overlap check.
print(f" - {range1.overlaps(range2)}\n")
AND (('start_date' BETWEEN STARTDATE AND ENDDATE) -- caters for inner and end date outerOR('end_date' BETWEEN STARTDATE AND ENDDATE) -- caters for inner and start date outerOR(STARTDATE BETWEEN 'start_date' AND 'end_date') -- only one needed for outer range where dates are inside.)
//custom date for example$d1 = new DateTime("2012-07-08");$d2 = new DateTime("2012-07-11");$d3 = new DateTime("2012-07-08");$d4 = new DateTime("2012-07-15");
//create a date period object$interval = new DateInterval('P1D');$daterange = iterator_to_array(new DatePeriod($d1, $interval, $d2));$daterange1 = iterator_to_array(new DatePeriod($d3, $interval, $d4));array_map(function($v) use ($daterange1) { if(in_array($v, $daterange1)) print "Bingo!";}, $daterange);
(Startdate BETWEEN '".$startdate2."' AND '".$enddate2."') //overlap: starts between start2/end2OR (Startdate < '".$startdate2."'AND (enddate = '0000-00-00' OR enddate >= '".$startdate2."')) //overlap: starts before start2 and enddate not set 0000-00-00 (still on going) or if enddate is set but higher then startdate2
CREATE FUNCTION IsOverlapDates(@startDate1 as datetime,@endDate1 as datetime,@startDate2 as datetime,@endDate2 as datetime)RETURNS intASBEGINDECLARE @Overlap as intSET @Overlap = (SELECT CASE WHEN ((@startDate1 BETWEEN @startDate2 AND @endDate2) -- caters for inner and end date outerOR(@endDate1 BETWEEN @startDate2 AND @endDate2) -- caters for inner and start date outerOR(@startDate2 BETWEEN @startDate1 AND @endDate1) -- only one needed for outer range where dates are inside.) THEN 1 ELSE 0 END)RETURN @Overlap
ENDGO
--Execution of the above codeDECLARE @startDate1 as datetimeDECLARE @endDate1 as datetimeDECLARE @startDate2 as datetimeDECLARE @endDate2 as datetimeDECLARE @Overlap as intSET @startDate1 = '2014-06-01 01:00:00'SET @endDate1 = '2014-06-01 02:00:00'SET @startDate2 = '2014-06-01 01:00:00'SET @endDate2 = '2014-06-01 01:30:00'
SET @Overlap = [dbo].[IsOverlapDates] (@startDate1, @endDate1, @startDate2, @endDate2)
SELECT Overlap = @Overlap
/*** Compares to comparable objects to find out whether they overlap.* It is assumed that the interval is in the format [from,to) (read: from is inclusive, to is exclusive).* A null value is interpreted as infinity*/function intervalsOverlap(from1, to1, from2, to2) {return (to2 === null || from1 < to2) && (to1 === null || to1 > from2);}
class Interval < ActiveRecord::Base
validates_presence_of :start_date, :end_date
# Check if a given interval overlaps this intervaldef overlaps?(other)(start_date - other.end_date) * (other.start_date - end_date) >= 0end
# Return a scope for all interval overlapping the given interval, including the given interval itselfnamed_scope :overlapping, lambda { |interval| {:conditions => ["id <> ? AND (DATEDIFF(start_date, ?) * DATEDIFF(?, end_date)) >= 0", interval.id, interval.end_date, interval.start_date]}}
end
MomentInterval a = MomentInterval.between(Instant.now(), Instant.now().plusSeconds(2));MomentInterval b = a.collapse(); // make b an empty interval out of a
System.out.println(a); // [2017-04-10T05:28:11,909000000Z/2017-04-10T05:28:13,909000000Z)System.out.println(b); // [2017-04-10T05:28:11,909000000Z/2017-04-10T05:28:11,909000000Z)
A = [StartA, EndA]B = [StartB, EndB]
[---- DateRange A ------] (True if StartA > EndB)[--- Date Range B -----]
[---- DateRange A -----] (True if EndA < StartB)[--- Date Range B ----]
重叠iff:(StartA <= EndB) and (EndA >= StartB)
案例2: A, B是开放区间
A = (StartA, EndA)B = (StartB, EndB)
(---- DateRange A ------) (True if StartA >= EndB)(--- Date Range B -----)
(---- DateRange A -----) (True if EndA <= StartB)(--- Date Range B ----)
重叠iff:(StartA < EndB) and (EndA > StartB)
案件3: A, B打开
A = [StartA, EndA)B = [StartB, EndB)
[---- DateRange A ------) (True if StartA >= EndB)[--- Date Range B -----)
[---- DateRange A -----) (True if EndA <= StartB)[--- Date Range B ----)
重叠条件:(StartA < EndB) and (EndA > StartB)
案件4: A, B打开
A = (StartA, EndA]B = (StartB, EndB]
(---- DateRange A ------] (True if StartA >= EndB)(--- Date Range B -----]
(---- DateRange A -----] (True if EndA <= StartB)(--- Date Range B ----]
重叠条件:(StartA < EndB) and (EndA > StartB)
案件5:A打开,B关闭
A = [StartA, EndA)B = [StartB, EndB]
[---- DateRange A ------) (True if StartA > EndB)[--- Date Range B -----]
[---- DateRange A -----) (True if EndA <= StartB)[--- Date Range B ----]
var isOverlapping = ((A == null || D == null || A <= D)&& (C == null || B == null || C <= B)&& (A == null || B == null || A <= B)&& (C == null || D == null || C <= D));
// For overlapping time intervals:areIntervalsOverlapping({ start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) },{ start: new Date(2014, 0, 17), end: new Date(2014, 0, 21) })//=> true