Intersecting overlapping intervals in Java

I have a set of date range values ​​that may overlap. Instead of combining these overlapping date ranges, I want to create new date ranges with adjusted dates, for example:

|---------------------–|
        |-----| 
            |--------------–|

must end in:

|-------|---|-|--------|----|

Is there an efficient way to solve this problem using Java?

Thanks in advance!

UPDATE: In my first question, I did not mention my own approach, so like this: I just take the beginning and end of the interval date and add it to the sorted set. Subsequently, I sorted through the set and created new intervals based on the reorganized dates.

+2
source share
5 answers

, . , . , , .

+2

Guava Range. Date, . RangeSet , , , ..

+3

:

  • .
  • .
    startIntervals - endIntervals, , 0, .
0

java.time

java.time.

LocalDate .

DateRange, .

public class DateRange {
    public LocalDate start , stop ;

    public DateRange ( LocalDate start , LocalDate stop ) {
        if(stop.isBefore(start)){
            throw new IllegalArgumentException ("The stop date is before the start date." );
        }
        this.start = start;
        this.stop = stop;
    }

    @Override
    public String toString () {
        return "DateRange{ " + "start=" + start + ", stop=" + stop + " }";
    }

}

.

    List<DateRange> ranges = new ArrayList<> ( 3 );
    ranges.add ( new DateRange ( LocalDate.of ( 2017 , Month.JANUARY , 17 ) , LocalDate.of ( 2017 , Month.MARCH , 7 ) ) );
    ranges.add ( new DateRange ( LocalDate.of ( 2017 , Month.FEBRUARY , 12 ) , LocalDate.of ( 2017 , Month.FEBRUARY , 16 ) ) );
    ranges.add ( new DateRange ( LocalDate.of ( 2017 , Month.FEBRUARY , 14 ) , LocalDate.of ( 2017 , Month.MARCH , 25 ) ) );

    System.out.println ( "ranges: " + ranges );

, List.

    // Intersect and combine to create a sequence of new DateRange objects.
    // Collect each start & stop as individual `LocalDate` objects.
    List<LocalDate> dates = new ArrayList<> ( ranges.size () * 2 );
    for ( DateRange range : ranges ) {
        dates.add ( range.start );
        dates.add ( range.stop );
    }

. , . , .

    // Sort the collection of dates.
    Collections.sort ( dates );

, .

    // Loop the sorted dates, creating DateRange objects as we go.
    List<DateRange> rangesOutput = new ArrayList<> ( dates.size () ); // Not an exact initial capacity but good enough.
    for ( int i = 1 ; i < dates.size () ; i ++ ) {
        LocalDate start = dates.get ( i - 1 ); // Subtract one for silly index counting.
        LocalDate stop = dates.get ( i + 1 - 1 ); // Subtract one for silly index counting. Or use ( i ) instead.
        if (  ! start.equals ( stop ) ) {  // If not equal, proceed. (If equal, ignore and move on to next loop.)
            DateRange range = new DateRange ( start , stop );
            rangesOutput.add ( range );
        }
    }
    System.out.println ( "rangesOutput: " + rangesOutput );

.

: [DateRange {start = 2017-01-17, stop = 2017-03-07}, DateRange {start = 2017-02-12, stop = 2017-02-16}, DateRange {start = 2017- 02-14, stop = 2017-03-25}]

rangeOutput: [DateRange {start = 2017-01-17, stop = 2017-02-12}, DateRange {start = 2017-02-12, stop = 2017-02-14}, DateRange {start = 2017- 02-14, stop = 2017-02-16}, DateRange {start = 2017-02-16, stop = 2017-03-07}, DateRange {start = 2017-03-07, stop = 2017-03-25} ]

IdeOne.com.


java.time

java.time Java 8 . legacy , java.util.Date, Calendar SimpleDateFormat.

Joda-Time, , java.time.

, . Oracle. Qaru . JSR 310.

java.time?

ThreeTen-Extra java.time . java.time. , Interval, YearWeek, YearQuarter .

0

Time4J, :

// create the intervals
SimpleInterval<Date> i1 = SimpleInterval.between(new Date(0L), new Date(5000L));
SimpleInterval<Date> i2 = SimpleInterval.between(new Date(0L), new Date(7000L));
SimpleInterval<Date> i3 = SimpleInterval.between(new Date(1000L), new Date(2000L));

// collect the intervals
IntervalCollection<Date> icoll =
    IntervalCollection.onTraditionalTimeLine().plus(i3).plus(i2).plus(i1);

// split and iterate
for (ChronoInterval<Date> interval : icoll.withSplits().getIntervals()) {
    System.out.println(interval);
}

:

[Thu Jan 01 01:00:00 CET 1970/Thu Jan 01 01:00:01 CET 1970)
[Thu Jan 01 01:00:01 CET 1970/Thu Jan 01 01:00:02 CET 1970)
[Thu Jan 01 01:00:02 CET 1970/Thu Jan 01 01:00:05 CET 1970)
[Thu Jan 01 01:00:05 CET 1970/Thu Jan 01 01:00:07 CET 1970)

withSplits() .

, , java.time.Instant Java-8 Time4J, Moment, PlainDate, PlainTimestamp ... .

0

All Articles