Datetime 确定两个日期范围是否重叠
给定两个日期范围,确定两个日期范围是否重叠的最简单或最有效的方法是什么Datetime 确定两个日期范围是否重叠,datetime,math,language-agnostic,Datetime,Math,Language Agnostic,给定两个日期范围,确定两个日期范围是否重叠的最简单或最有效的方法是什么 例如,假设我们有由日期时间变量StartDate1到EndDate1和StartDate2到EndDate2表示的范围。我认为,如果出现以下情况,可以说这两个范围重叠: (StartDate1 <= EndDate2) and (StartDate2 <= EndDate1) A.end >= B.start AND A.start <= B.end (StartDate1我认为,如果出现以下情况
例如,假设我们有由日期时间变量
StartDate1
到EndDate1
和StartDate2
到EndDate2表示的范围。我认为,如果出现以下情况,可以说这两个范围重叠:
(StartDate1 <= EndDate2) and (StartDate2 <= EndDate1)
A.end >= B.start AND A.start <= B.end
(StartDate1我认为,如果出现以下情况,可以说这两个范围重叠:
(StartDate1 <= EndDate2) and (StartDate2 <= EndDate1)
A.end >= B.start AND A.start <= B.end
(开始日期1我愿意
StartDate1.IsBetween(StartDate2, EndDate2) || EndDate1.IsBetween(StartDate2, EndDate2)
其中,IsBetween
类似于
public static bool IsBetween(this DateTime value, DateTime left, DateTime right) {
return (value > left && value < right) || (value < left && value > right);
}
public static bool IsBetween(此日期时间值,左日期时间,右日期时间){
返回(值>左和值<右)| |(值<左和值>右);
}
我愿意
StartDate1.IsBetween(StartDate2, EndDate2) || EndDate1.IsBetween(StartDate2, EndDate2)
其中,IsBetween
类似于
public static bool IsBetween(this DateTime value, DateTime left, DateTime right) {
return (value > left && value < right) || (value < left && value > right);
}
public static bool IsBetween(此日期时间值,左日期时间,右日期时间){
返回(值>左和值<右)| |(值<左和值>右);
}
我认为最简单的方法是比较EndDate1是否在StartDate2之前,EndDate2是否在StartDate1之前
当然,如果您考虑的是开始日期总是在结束日期之前的时间间隔。我认为最简单的方法是比较EndDate1是否在开始日期2之前,EndDate2是否在开始日期1之前
当然,如果您考虑的是StartDate始终在EndDate之前的时间间隔。(StartA=StartB)
证明:
让条件A表示日期范围A完全在日期范围B之后
_ |---- DateRange A ------|
|---Date Range B -----| _
|---- DateRange A -----| _
_ |---Date Range B ----|
(如果StartA>EndB
,则为真)
条件B表示日期范围A完全在日期范围B之前
_ |---- DateRange A ------|
|---Date Range B -----| _
|---- DateRange A -----| _
_ |---Date Range B ----|
(如果EndA
,则为真)
如果A和B都不为真,则存在重叠-
(如果一个范围既不完全在另一个范围之后,
也不完全是在对方之前,,
那么它们必须重叠。)
现在其中一位说:
非(A或B)
非A和非B
翻译成:(StartA=StartB)
注意:这包括边完全重叠的情况。如果要排除此情况,
将=
运算符更改为
,并(StartA=StartB)
证明:
让条件A表示日期范围A完全在日期范围B之后
_ |---- DateRange A ------|
|---Date Range B -----| _
|---- DateRange A -----| _
_ |---Date Range B ----|
(如果StartA>EndB
,则为真)
条件B表示日期范围A完全在日期范围B之前
_ |---- DateRange A ------|
|---Date Range B -----| _
|---- DateRange A -----| _
_ |---Date Range B ----|
(如果EndA
,则为真)
如果A和B都不为真,则存在重叠-
(如果一个范围既不完全在另一个范围之后,
也不完全是在对方之前,,
那么它们必须重叠。)
现在其中一位说:
非(A或B)
非A和非B
翻译成:(StartA=StartB)
注意:这包括边完全重叠的情况。如果要排除此情况,
将< <代码> > <代码> >运算符> <代码> >代码> >代码> < P>为时间关系的推理(或任何其他的间隔关系,来此),考虑。它描述了两个区间之间可能存在的13种可能的关系。你可以找到其他的参考文献——“艾伦区间”。这似乎是一个有效的搜索词。你也可以在Snodgrass(网址为在线PDF)以及Date、Darwen和Lorentzos(2002)或(2014;实际上是TD&RM的第二版)中找到关于这些操作的信息
简短的(ish)答案是:给定两个日期间隔A
和B
,其中包含组件.start
和.end
以及约束.start,用于推理时间关系(或任何其他时间间隔关系,到此为止)它描述了两个区间之间可能存在的13种可能的关系。你可以找到其他的引用——“艾伦区间”似乎是一个可操作的搜索词。你也可以在Snodgrass的(在URL上可用的PDF)中找到关于这些操作的信息,并且在日期,达温和洛伦茨(2002)或(2014年;实际上是TD&RM的第二版)
简短的(ish)答案是:给定两个日期间隔A
和B
,包含组件.start
和.end
以及约束.start,这里有一个通用方法,可以在本地使用
// 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 list
where filter(t1)
from t2 in list
where !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 >= in2
let 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 PM
Name:Lisa T1In:1/1/2008 7:00:00 PM T1Out:1/1/2008 9:00:00 PM
Done
*/
}
//获取一个列表并返回具有重叠时间范围的所有记录。
公共静态IEnumerable GetOverlappedTimes(IEnumerable列表、Func筛选器、Func开始、Func结束)
{
//选择左侧与filter()匹配的所有记录,并返回右侧重叠的所有记录。
var重叠=从列表中的t1开始
其中过滤器(t1)
从列表中的t2开始
其中!object.Equals(t1,t2)//不匹配右侧的相同记录。
让in1=开始(t1)
让出1=结束(t1)
让in2=开始(t2)
让出口2=结束(t2)
其中in1=in2
让totover=getmin(in1,out1,in2,out2)
选择t2;
返回重叠;
}
公共静态void TestOverlap()
{
var tl1=new-testimeentry(){ID=1,Name=“Bill”,In=“1/1/08 1:00pm”。ToDate(),Out=“1/1/08 4:00pm”。ToDate();
var tl2=new-testimeentry(){ID=2,Name=“John”,In=“1/1/08 5:00pm.ToDate(),Out=“1/1/08 6:00pm.ToDate();
var tl3=new-testimeentry(){ID=3,Name=“Lisa”,In=“1/1/08 7:00pm.ToDate(),Out=“1/1/08 9:00pm.ToDate();
var tl4=new-testimeentry(){ID=4,Name=“Joe”,In=“1/1/08 3:00pm.ToDate(),Out=“1/1/08 8:00pm.ToDate();
var tl5=new testimeentry(){ID=1,N
//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/end2
OR (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 int
AS
BEGIN
DECLARE @Overlap as int
SET @Overlap = (SELECT CASE WHEN (
(@startDate1 BETWEEN @startDate2 AND @endDate2) -- caters for inner and end date outer
OR
(@endDate1 BETWEEN @startDate2 AND @endDate2) -- caters for inner and start date outer
OR
(@startDate2 BETWEEN @startDate1 AND @endDate1) -- only one needed for outer range where dates are inside.
) THEN 1 ELSE 0 END
)
RETURN @Overlap
END
GO
--Execution of the above code
DECLARE @startDate1 as datetime
DECLARE @endDate1 as datetime
DECLARE @startDate2 as datetime
DECLARE @endDate2 as datetime
DECLARE @Overlap as int
SET @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
public static class NumberExtensionMethods
{
public static Boolean IsBetween(this Int64 value, Int64 Min, Int64 Max)
{
if (value >= Min && value <= Max) return true;
else return false;
}
public static Boolean IsBetween(this DateTime value, DateTime Min, DateTime Max)
{
Int64 numricValue = value.Ticks;
Int64 numericStartDate = Min.Ticks;
Int64 numericEndDate = Max.Ticks;
if (numricValue.IsBetween(numericStartDate, numericEndDate) )
{
return true;
}
return false;
}
}
public static Boolean IsOverlap(DateTime startDate1, DateTime endDate1, DateTime startDate2, DateTime endDate2)
{
Int64 numericStartDate1 = startDate1.Ticks;
Int64 numericEndDate1 = endDate1.Ticks;
Int64 numericStartDate2 = startDate2.Ticks;
Int64 numericEndDate2 = endDate2.Ticks;
if (numericStartDate2.IsBetween(numericStartDate1, numericEndDate1) ||
numericEndDate2.IsBetween(numericStartDate1, numericEndDate1) ||
numericStartDate1.IsBetween(numericStartDate2, numericEndDate2) ||
numericEndDate1.IsBetween(numericStartDate2, numericEndDate2))
{
return true;
}
return false;
}
if (IsOverlap(startdate1, enddate1, startdate2, enddate2))
{
Console.WriteLine("IsOverlap");
}
TEST1: (X <= A || X >= B)
&&
TEST2: (Y >= B || Y <= A)
&&
TEST3: (X >= B || Y <= A)
X-------------Y
A-----B
TEST1: TRUE
TEST2: TRUE
TEST3: FALSE
RESULT: FALSE
---------------------------------------
X---Y
A---B
TEST1: TRUE
TEST2: TRUE
TEST3: TRUE
RESULT: TRUE
---------------------------------------
X---Y
A---B
TEST1: TRUE
TEST2: TRUE
TEST3: TRUE
RESULT: TRUE
---------------------------------------
X----Y
A---------------B
TEST1: FALSE
TEST2: FALSE
TEST3: FALSE
RESULT: FALSE
public static boolean checkTimeOverlaps(Date startDate1, Date endDate1, Date startDate2, Date endDate2)
{
if (startDate1 == null || endDate1 == null || startDate2 == null || endDate2 == null)
return false;
if ((startDate1.getTime() <= endDate2.getTime()) && (startDate2.getTime() <= endDate1.getTime()))
return true;
return false;
}
class Interval < ActiveRecord::Base
validates_presence_of :start_date, :end_date
# Check if a given interval overlaps this interval
def overlaps?(other)
(start_date - other.end_date) * (other.start_date - end_date) >= 0
end
# Return a scope for all interval overlapping the given interval, including the given interval itself
named_scope :overlapping, lambda { |interval| {
:conditions => ["id <> ? AND (DATEDIFF(start_date, ?) * DATEDIFF(?, end_date)) >= 0", interval.id, interval.end_date, interval.start_date]
}}
end
SELECT DISTINCT T1.EmpID
FROM Table1 T1
INNER JOIN Table2 T2 ON T1.EmpID = T2.EmpID
AND T1.JobID <> T2.JobID
AND (
(T1.DateFrom >= T2.DateFrom AND T1.dateFrom <= T2.DateTo)
OR (T1.DateTo >= T2.DateFrom AND T1.DateTo <= T2.DateTo)
OR (T1.DateFrom < T2.DateFrom AND T1.DateTo IS NULL)
)
AND NOT (T1.DateFrom = T2.DateFrom)
(startB <= startA && endB > startA)
|| (startB >= startA && startB < endA)
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)
System.out.println(
"startA < endB: " + a.getStartAsInstant().isBefore(b.getEndAsInstant())); // false
System.out.println(
"endA > startB: " + a.getEndAsInstant().isAfter(b.getStartAsInstant())); // true
System.out.println("a overlaps b: " + a.intersects(b)); // a overlaps b: false
A = [StartA, EndA]
B = [StartB, EndB]
[---- DateRange A ------] (True if StartA > EndB)
[--- Date Range B -----]
[---- DateRange A -----] (True if EndA < StartB)
[--- Date Range 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 ----)
A = [StartA, EndA)
B = [StartB, EndB)
[---- DateRange A ------) (True if StartA >= EndB)
[--- Date Range B -----)
[---- DateRange A -----) (True if EndA <= StartB)
[--- Date Range 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 ----]
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));
function isOverlapping(startDate1, endDate1, startDate2, endDate2){
return moment(startDate1).isSameOrBefore(endDate2) &&
moment(startDate2).isSameOrBefore(endDate1);
}
(StartDate1, EndDate1) overlaps (StartDate2, EndDate2)
daterange(StartDate1, EndDate1) @> daterange(StartDate2, EndDate2)