datetime - निर्धारित करें कि दो दिनांक सीमा ओवरलैप है या नहीं




math language-agnostic (25)

यदि आप एक तिथि सीमा का उपयोग कर रहे हैं जो अभी तक समाप्त नहीं हुआ है (अभी भी चल रहा है) उदाहरण के लिए endDate = '0000-00-00' सेट नहीं है, तो आप 0000-00-00 मान्य दिनांक नहीं है!

मैंने इस समाधान का उपयोग किया:

(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

अगर startdate2 अधिक है तो अंत में कोई ओवरलैप नहीं है!

दो तारीख सीमाओं को देखते हुए, यह निर्धारित करने का सबसे सरल या सबसे प्रभावी तरीका क्या है कि दो दिनांक सीमाएं ओवरलैप हैं या नहीं?

उदाहरण के तौर पर, मान लीजिए कि हमारे पास डेटटाइम वेरिएबल्स StartDate1 से EndDate1 और StartDate2 को EndDate2 तक EndDate2


यदि ओवरलैप की गणना भी की जानी चाहिए, तो आप निम्न सूत्र का उपयोग कर सकते हैं:

overlap = max(0, min(EndDate1, EndDate2) - max(StartDate1, StartDate2))
if (overlap > 0) { 
    ...
}

नीचे प्रश्न मुझे उन आईडी को देता है जिनके लिए आपूर्ति की गई तिथि सीमा (प्रारंभ और समाप्ति तिथियां मेरी तालिका_नाम में किसी भी तारीख (प्रारंभ और समाप्ति तिथियों) के साथ ओवरलैप होती हैं

select id from table_name where (START_DT_TM >= 'END_DATE_TIME'  OR   
(END_DT_TM BETWEEN 'START_DATE_TIME' AND 'END_DATE_TIME'))

if (StartDate1 > StartDate2) swap(StartDate, EndDate);

(StartDate1 <= EndDate2) and (StartDate2 <= EndDate1);

मेरी राय में ऐसा करने का सबसे आसान तरीका यह तुलना करना होगा कि अगर EndDate1 StartDate2 से पहले है और EndDate2 StartDate1 से पहले है।

बेशक यदि आप अंतराल पर विचार कर रहे हैं जहां StartDate हमेशा EndDate से पहले है।


For ruby I also found this:

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

Found it here with nice explaination -> http://makandracards.com/makandra/984-test-if-two-date-ranges-overlap-in-ruby-or-rails


अस्थायी संबंधों (या किसी अन्य अंतराल संबंधों के बारे में तर्क के लिए, उस पर आना), एलन के अंतराल बीजगणित पर विचार करें। यह 13 संभावित संबंधों का वर्णन करता है कि दो अंतराल एक-दूसरे के संबंध में हो सकते हैं। आप अन्य संदर्भ पा सकते हैं - "एलन अंतराल" एक ऑपरेटिव खोज शब्द प्रतीत होता है। आप इन परिचालनों के बारे में जानकारी एसक्यूएलग्रैस के विकास समय-उन्मुख अनुप्रयोगों में एसक्यूएल (पीडीएफ ऑनलाइन यूआरएल पर ऑनलाइन उपलब्ध), और डेट, डार्वेन और लोरेंटेजोस टेम्पोरल डेटा और रिलेशनल मॉडल (2002) या समय और रिलेशनल थ्योरी में: अस्थायी डेटाबेस में इन परिचालनों के बारे में जानकारी भी प्राप्त कर सकते हैं : रिलेशनल मॉडल और एसक्यूएल (2014; प्रभावी रूप से टीडी और आरएम का दूसरा संस्करण)।

छोटा (आईएसएच) उत्तर है: दो दिनांक अंतराल A और B को घटकों के साथ दिया गया है। .start और .end और बाधा .start <= .end , फिर दो अंतराल ओवरलैप करें यदि:

A.end >= B.start AND A.start <= B.end

आप ओवरलैप की डिग्री के लिए अपनी आवश्यकताओं को पूरा करने के लिए >= बनाम > और <= बनाम < के उपयोग को ट्यून कर सकते हैं।

एरिक टिप्पणियां:

यदि आप चीजों को मजाकिया मानते हैं तो आप केवल 13 प्राप्त कर सकते हैं ... जब मैं इसके साथ पागल हो जाता हूं तो मुझे "दो संभावित अंतराल मिल सकते हैं"। समझदार गिनती से, मुझे केवल छः मिलते हैं, और यदि आप देखभाल करते हैं कि ए या बी पहले आता है, तो मुझे केवल तीन मिलते हैं (कोई अंतर नहीं, आंशिक रूप से अंतरण, एक पूरी तरह से दूसरे के भीतर)। 15 इस तरह से चला जाता है: [पहले: पहले, शुरू, भीतर, अंत, बाद में], [प्रारंभ: शुरू, भीतर, अंत, बाद], [भीतर: भीतर, अंत, बाद], [अंत: अंत, बाद], [ के बाद: के बाद]।

मुझे लगता है कि आप पहले से पहले और बाद में 'बाद में' दो प्रविष्टियों की गणना नहीं कर सकते हैं। यदि आप अपने इनवर्ड्स के साथ कुछ संबंधों को समझाते हैं तो मैं 7 प्रविष्टियों को देख सकता हूं (संदर्भित विकिपीडिया यूआरएल में आरेख देखें; इसमें 7 प्रविष्टियां हैं, जिनमें से 6 में एक अलग उलटा है, जिसमें एक अलग विपरीत नहीं है)। और क्या तीन समझदार है आपकी आवश्यकताओं पर निर्भर करता है।

----------------------|-------A-------|----------------------
    |----B1----|
           |----B2----|
               |----B3----|
               |----------B4----------|
               |----------------B5----------------|
                      |----B6----|
----------------------|-------A-------|----------------------
                      |------B7-------|
                      |----------B8-----------|
                         |----B9----|
                         |----B10-----|
                         |--------B11--------|
                                      |----B12----|
                                         |----B13----|
----------------------|-------A-------|----------------------

मेरा मानना ​​है कि यह कहना पर्याप्त है कि दो श्रेणियां ओवरलैप हैं यदि:

(StartDate1 <= EndDate2) and (StartDate2 <= EndDate1)

माइक्रोसॉफ्ट एसक्यूएल सर्वर - एसक्यूएल फंक्शन में

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

जावास्क्रिप्ट का उपयोग कर अभी तक एक और समाधान है। मेरे समाधान की विशेषताएं:

  • अनंत मूल्यों को अनंतता के रूप में संभालता है
  • मान लें कि निचली सीमा समावेशी है और ऊपरी बाध्य अनन्य है।
  • परीक्षणों का एक गुच्छा के साथ आता है

परीक्षण पूर्णांक पर आधारित होते हैं लेकिन चूंकि जावास्क्रिप्ट में दिनांक वस्तुएं तुलनात्मक हैं, इसलिए आप केवल दो दिनांक वस्तुओं में फेंक सकते हैं। या आप मिलीसेकंद टाइमस्टैंप में फेंक सकते हैं।

कोड:

/**
 * 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);
}

टेस्ट:

describe('', function() {
    function generateTest(firstRange, secondRange, expected) {
        it(JSON.stringify(firstRange) + ' and ' + JSON.stringify(secondRange), function() {
            expect(intervalsOverlap(firstRange[0], firstRange[1], secondRange[0], secondRange[1])).toBe(expected);
        });
    }

    describe('no overlap (touching ends)', function() {
        generateTest([10,20], [20,30], false);
        generateTest([20,30], [10,20], false);

        generateTest([10,20], [20,null], false);
        generateTest([20,null], [10,20], false);

        generateTest([null,20], [20,30], false);
        generateTest([20,30], [null,20], false);
    });

    describe('do overlap (one end overlaps)', function() {
        generateTest([10,20], [19,30], true);
        generateTest([19,30], [10,20], true);

        generateTest([10,20], [null,30], true);
        generateTest([10,20], [19,null], true);
        generateTest([null,30], [10,20], true);
        generateTest([19,null], [10,20], true);
    });

    describe('do overlap (one range included in other range)', function() {
        generateTest([10,40], [20,30], true);
        generateTest([20,30], [10,40], true);

        generateTest([10,40], [null,null], true);
        generateTest([null,null], [10,40], true);
    });

    describe('do overlap (both ranges equal)', function() {
        generateTest([10,20], [10,20], true);

        generateTest([null,20], [null,20], true);
        generateTest([10,null], [10,null], true);
        generateTest([null,null], [null,null], true);
    });
});

कर्म और चमेली और फैंटॉमजेएस के साथ दौड़ते समय परिणाम:

फैंटॉमजेएस 1.9.8 (लिनक्स): 20 सफल 20 में से 20 निष्पादित (0.003 सेकंड / 0.004 सेकंड)


जावा में मेरा समाधान यहां है, जो असंबद्ध अंतराल पर भी काम करता है

private Boolean overlap (Timestamp startA, Timestamp endA,
                         Timestamp startB, Timestamp endB)
{
    return (endB == null || startA == null || !startA.after(endB))
        && (endA == null || startB == null || !endA.before(startB));
}

यहां पोस्ट किया गया समाधान सभी ओवरलैपिंग श्रेणियों के लिए काम नहीं करता है ...

----------------------|-------A-------|----------------------
    |----B1----|
           |----B2----|
               |----B3----|
               |----------B4----------|
               |----------------B5----------------|
                      |----B6----|
----------------------|-------A-------|----------------------
                      |------B7-------|
                      |----------B8-----------|
                         |----B9----|
                         |----B10-----|
                         |--------B11--------|
                                      |----B12----|
                                         |----B13----|
----------------------|-------A-------|----------------------

मेरा कामकाजी समाधान था:

AND (
  ('start_date' BETWEEN STARTDATE AND ENDDATE) -- caters for inner and end date outer
  OR
  ('end_date' BETWEEN STARTDATE AND ENDDATE) -- caters for inner and start date outer
  OR
  (STARTDATE BETWEEN 'start_date' AND 'end_date') -- only one needed for outer range where dates are inside.
) 

This was my solution, it returns true when the values don't overlap:

X START 1 Y END 1

A START 2 B END 2

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

आप इसे आजमा सकते हैं:

//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);

सबसे आसान

सबसे आसान तरीका डेट-टाइम काम के लिए एक अच्छी तरह से इंजीनियर समर्पित पुस्तकालय का उपयोग करना है।

someInterval.overlaps( anotherInterval )

जावा। टाइम और थ्रीटेन-अतिरिक्त

व्यवसाय में सबसे अच्छा जावा 8 और बाद में जावा java.time फ्रेमवर्क बनाया गया है। ThreeTen-Extra परियोजना जो अतिरिक्त कक्षाओं के साथ जावा.टाइम को पूरक करती है, विशेष रूप से Interval वर्ग जिसे हमें यहां चाहिए।

इस प्रश्न पर language-agnostic टैग के लिए, दोनों परियोजनाओं के लिए स्रोत कोड अन्य भाषाओं में उपयोग के लिए उपलब्ध है (उनके लाइसेंस दिमाग)।

Interval

Interval कक्षा आसान है, लेकिन तारीख-केवल मूल्यों के बजाय दिनांक-समय के क्षणों ( java.time.Instant ऑब्जेक्ट्स) की आवश्यकता होती है। तो हम तिथि का प्रतिनिधित्व करने के लिए यूटीसी में दिन के पहले पल का उपयोग करके आगे बढ़ते हैं।

Instant start = Instant.parse( "2016-01-01T00:00:00Z" );
Instant stop = Instant.parse( "2016-02-01T00:00:00Z" );

उस अवधि का प्रतिनिधित्व करने के लिए Interval बनाएं।

Interval interval_A = Interval.of( start , stop );

हम एक प्रारंभिक पल और एक Duration साथ Interval को भी परिभाषित कर सकते हैं।

Instant start_B = Instant.parse( "2016-01-03T00:00:00Z" );
Interval interval_B = Interval.of( start_B , Duration.of( 3 , ChronoUnit.DAYS ) );

ओवरलैप के लिए परीक्षण की तुलना करना आसान है।

Boolean overlaps = interval_A.overlaps( interval_B );

आप एक Interval तुलना किसी अन्य Interval या Instant खिलाफ कर सकते हैं:

इनमें से सभी समय की अवधि को परिभाषित करने के लिए Half-Open दृष्टिकोण का उपयोग करते हैं जहां शुरुआत समावेशी है और अंत अनन्य है


यहां एक सामान्य विधि है जो स्थानीय रूप से उपयोगी हो सकती है।

    // 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
         */
    }

Split the problem into cases then handle each case .

The situation 'two date ranges intersect' is covered by two cases - the first date range starts within the second, or the second date range starts within the first.


मुझे क्या करना होगा

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);
    }

जवाब मेरे लिए बहुत आसान है इसलिए मैंने एक अधिक सामान्य गतिशील एसक्यूएल कथन बनाया है जो यह देखने के लिए जांचता है कि किसी व्यक्ति के पास कोई ओवरलैपिंग तिथियां हैं या नहीं।

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)

(स्टार्ट ए <= एंडबी) और (एंडए> = स्टार्टबी)

प्रमाण:
कंडीशनए का मतलब है कि तिथि सीमा के बाद डेटरेंज पूरी तरह से दिनांक बी
_ |---- DateRange A ------| |---Date Range B -----| _
(यदि StartA > EndB ) सही है

कंडीशनबी का मतलब है कि डेटरेंज ए डेटरेंज बी से पहले पूरी तरह से है
|---- DateRange A -----| _ _ |---Date Range B ----|
(सच है अगर EndA < StartB )

फिर ओवरलैप मौजूद है यदि न तो ए और बी सत्य है -
(यदि एक सीमा न तो दूसरे के बाद पूरी तरह से है,
न ही दूसरे से पहले, फिर उन्हें ओवरलैप करना होगा।)

अब डी मॉर्गन के कानूनों में से एक का कहना है कि:

Not (A Or B) <=> Not A And Not B

जो अनुवाद करता है: (StartA <= EndB) and (EndA >= StartB)

नोट: इसमें ऐसी स्थितियां शामिल हैं जहां किनारों को बिल्कुल ओवरलैप किया जाता है। अगर आप इसे बाहर करना चाहते हैं,
>= ऑपरेटरों को > और <= to < बदलें

नोट 2। @ बाओदाद के लिए धन्यवाद, इस ब्लॉग को देखें, वास्तविक ओवरलैप निम्न में से कम है:
{ endB-startA , endB - startB , endB-startA , endB - startB }

(StartA <= EndB) and (EndA >= StartB) (StartA <= EndB) and (StartB <= EndA)

नोट 3। @ टॉमोसियस के लिए धन्यवाद, एक छोटा संस्करण पढ़ता है:
DateRangesOverlap = max(start1, start2) < min(end1, end2)
यह वास्तव में एक लंबे समय तक कार्यान्वयन के लिए एक वाक्य रचनात्मक शॉर्टकट है, जिसमें यह सत्यापित करने के लिए अतिरिक्त चेक शामिल हैं कि प्रारंभ दिनांक अंतराल पर या उससे पहले हैं। उपरोक्त से इसे प्राप्त करना:

यदि प्रारंभ और समाप्ति तिथियां आदेश से बाहर हो सकती हैं, यानी, यदि यह संभव है कि startA > endA या startB > endB , तो आपको यह भी जांचना होगा कि वे क्रम में हैं, इसलिए इसका मतलब है कि आपको दो अतिरिक्त वैधता नियम जोड़ना होगा:
(StartA <= EndB) and (StartB <= EndA) and (StartA <= EndA) and (StartB <= EndB) या:
(StartA <= EndB) and (StartA <= EndA) and (StartB <= EndA) and (StartB <= EndB) या,
(StartA <= Min(EndA, EndB) and (StartB <= Min(EndA, EndB)) या:
(Max(StartA, StartB) <= Min(EndA, EndB)

लेकिन Min() और Max() को लागू करने के लिए, आपको कोड करना होगा, (टर्नेसनेस के लिए सी टर्नरी का उपयोग करना) ,:
(StartA > StartB? Start A: StartB) <= (EndA < EndB? EndA: EndB)


यह पल.जेएस के साथ मेरा जावास्क्रिप्ट समाधान था:

// Current row dates
var dateStart = moment("2014-08-01", "YYYY-MM-DD");
var dateEnd = moment("2014-08-30", "YYYY-MM-DD");

// Check with dates above
var rangeUsedStart = moment("2014-08-02", "YYYY-MM-DD");
var rangeUsedEnd = moment("2014-08-015", "YYYY-MM-DD");

// Range covers other ?
if((dateStart <= rangeUsedStart) && (rangeUsedEnd <= dateEnd)) {
    return false;
}
// Range intersects with other start ?
if((dateStart <= rangeUsedStart) && (rangeUsedStart <= dateEnd)) {
    return false;
}
// Range intersects with other end ?
if((dateStart <= rangeUsedEnd) && (rangeUsedEnd <= dateEnd)) {
    return false;
}

// All good
return true;

@ ब्रेटाना द्वारा दिए गए गणितीय समाधान अच्छे हैं लेकिन दो विशिष्ट विवरणों की उपेक्षा करते हैं:

  1. बंद या आधे खुले अंतराल के पहलू
  2. खाली अंतराल

अंतराल सीमाओं की बंद या खुली स्थिति के बारे में, @ अंतराल का समाधान बंद अंतराल के लिए मान्य है

(स्टार्ट ए <= एंडबी) और (एंडए> = स्टार्टबी)

आधे खुले अंतराल के लिए फिर से लिखा जा सकता है:

(स्टार्ट ए <एंडबी) और (एंड ए> स्टार्टबी)

यह सुधार आवश्यक है क्योंकि एक खुली अंतराल सीमा परिभाषा के अंतराल की मान सीमा से संबंधित नहीं है।

और खाली अंतराल के बारे में, ठीक है, ऊपर दिखाया गया रिश्ता पकड़ नहीं है। खाली अंतराल जिसमें परिभाषा के अनुसार कोई वैध मान नहीं है, विशेष मामले के रूप में संभाला जाना चाहिए। मैं इसे अपने जावा टाइम लाइब्रेरी टाइम 4 Time4J द्वारा इस उदाहरण के माध्यम से प्रदर्शित करता हूं:

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

As shown above, empty intervals violate the overlap condition above (especially startA < endB), so Time4J (and other libraries, too) has to handle it as special edge case in order to guarantee that the overlap of any arbitrary interval with an empty interval does not exist. Of course, date intervals (which are closed by default in Time4J but can be half-open, too, like empty date intervals) are handled in a similar way.


मुझे पता है कि इसे भाषा-अज्ञेयवादी के रूप में टैग किया गया है, लेकिन आप सभी जावा में कार्यान्वित करने के लिए: पहिया को पुन: पेश न करें और जोदा समय का उपयोग न करें।

http://joda-time.sourceforge.net/api-release/org/joda/time/base/AbstractInterval.html#overlaps(org.joda.time.ReadableInterval )


यह आलेख .NET के लिए समय अवधि लाइब्रेरी गणना अवधि द्वारा दो समयावधि के संबंध का वर्णन करता है:

// ------------------------------------------------------------------------
public enum PeriodRelation
{
    After,
    StartTouching,
    StartInside,
    InsideStartTouching,
    EnclosingStartTouching,
    Enclosing,
    EnclosingEndTouching,
    ExactMatch,
    Inside,
    InsideEndTouching,
    EndInside,
    EndTouching,
    Before,
} // enum PeriodRelation


मुझे विश्वास नहीं है कि ढांचे में स्वयं ही इस वर्ग है। शायद एक तीसरी पार्टी पुस्तकालय ...

लेकिन इस जटिलता को संभालने के लिए अवधि मूल्य-वस्तु वर्ग क्यों नहीं बनाते? इस तरह आप अन्य बाधाओं को सुनिश्चित कर सकते हैं, जैसे स्टार्ट बनाम एंड डेटटाइम को मान्य करना। कुछ इस तरह:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Whatever.Domain.Timing {
    public class Period {
        public DateTime StartDateTime {get; private set;}
        public DateTime EndDateTime {get; private set;}

        public Period(DateTime StartDateTime, DateTime EndDateTime) {
            if (StartDateTime > EndDateTime)
                throw new InvalidPeriodException("End DateTime Must Be Greater Than Start DateTime!");
            this.StartDateTime = StartDateTime;
            this.EndDateTime = EndDateTime;
        }


        public bool Overlaps(Period anotherPeriod){
            return (this.StartDateTime < anotherPeriod.EndDateTime && anotherPeriod.StartDateTime < this.EndDateTime)
        }

        public TimeSpan GetDuration(){
            return EndDateTime - StartDateTime;
        }

    }

    public class InvalidPeriodException : Exception {
        public InvalidPeriodException(string Message) : base(Message) { }    
    }
}

इस तरह आप प्रत्येक अवधि की व्यक्तिगत रूप से तुलना करने में सक्षम होंगे ...





datetime math language-agnostic