added union, intersection and open ranges to TimeRange

This commit is contained in:
Fredrik Teschke committed 2014-02-15 21:32:26 +01:00
1 parent 924d6e0d1f
commit 6d52cc1354
4 files changed
+117 -11

No files matched your search

@@ -2,13 +2,9 @@ package com.sap.sailing.domain.common;
import java.io.Serializable;
/**
* A TimeRange defined by a starting timepoint {@link #from()}, and an ending timepoint {@link #to()}, which are both inclusive.
* @author Fredrik Teschke
*
*/
public interface TimeRange extends Comparable<TimeRange>, Serializable {
TimePoint from();
TimePoint to();
/**
@@ -35,6 +31,16 @@ public interface TimeRange extends Comparable<TimeRange>, Serializable {
boolean endsAfter(TimeRange other);
/**
* Is the time range open ended towards older timepoints?
*/
boolean openBeginning();
/**
* Is the time range open ended towards newer timepoints?
*/
boolean openEnd();
/**
* Get time-difference between the timepoint and this timerange.
* It will be 0 if the timepoint lies within the timerange, otherwise the time-difference
@@ -43,4 +49,14 @@ public interface TimeRange extends Comparable<TimeRange>, Serializable {
* @return
*/
long timeDifference(TimePoint timePoint);
/**
* Merges the two ranges, only possible if {@code other} {@link #intersects()} this range.
*/
TimeRange union(TimeRange other);
/**
* Intersection of the two ranges, only possible if {@code other} {@link #intersects()} this range.
*/
TimeRange intersection(TimeRange other);
}
@@ -5,17 +5,19 @@ import com.sap.sailing.domain.common.TimeRange;
import com.sap.sailing.domain.common.impl.Util.Pair;
public class TimeRangeImpl extends Pair<TimePoint, TimePoint> implements TimeRange {
public static final TimePoint BeginningOfTime = new MillisecondsTimePoint(Long.MIN_VALUE);
public static final TimePoint EndOfTime = new MillisecondsTimePoint(Long.MAX_VALUE);
private static final long serialVersionUID = 8710198176227507300L;
public TimeRangeImpl(TimePoint from, TimePoint to) {
super(from, to);
if (from.after(to)) throw new IllegalArgumentException(String.format("from (%s) must lie before to (%s) in a TimeRange", from, to));
super(from == null ? BeginningOfTime : from, to == null ? EndOfTime : to);
if (from().after(to())) throw new IllegalArgumentException(String.format("from (%s) must lie before to (%s) in a TimeRange", from(), to()));
}
@Override
public int compareTo(TimeRange arg0) {
// TODO Auto-generated method stub
return 0;
public int compareTo(TimeRange other) {
if (other.from() == from() && other.to() == to()) return 0;
return startsBefore(other) ? -1 : 1;
}
@Override
@@ -30,7 +32,7 @@ public class TimeRangeImpl extends Pair<TimePoint, TimePoint> implements TimeRan
@Override
public boolean liesWithin(TimeRange other) {
return from().compareTo(other.from()) >= 0 && to().compareTo(other.to()) <=0;
return from().compareTo(other.from()) >= 0 && to().compareTo(other.to()) <= 0;
}
@Override
@@ -64,4 +66,30 @@ public class TimeRangeImpl extends Pair<TimePoint, TimePoint> implements TimeRan
if (timePoint.before(from())) return from().asMillis() - timePoint.asMillis();
return to().asMillis() - timePoint.asMillis();
}
@Override
public TimeRange union(TimeRange other) {
if (! intersects(other)) return null;
TimePoint newFrom = startsBefore(other) ? from() : other.from();
TimePoint newTo = endsAfter(other) ? to() : other.to();
return new TimeRangeImpl(newFrom, newTo);
}
@Override
public boolean openBeginning() {
return from().equals(BeginningOfTime);
}
@Override
public boolean openEnd() {
return to().equals(EndOfTime);
}
@Override
public TimeRange intersection(TimeRange other) {
if (! intersects(other)) return null;
TimePoint newFrom = startsBefore(other) ? other.from() : from();
TimePoint newTo = endsAfter(other) ? other.to() : to();
return new TimeRangeImpl(newFrom, newTo);
}
}
@@ -1,5 +1,9 @@
package com.sap.sailing.domain.common.test;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import junit.framework.Assert;
import org.junit.Test;
@@ -54,4 +58,62 @@ public class TimeRangeTest {
Assert.assertTrue(one.intersects(two));
Assert.assertTrue(two.intersects(one));
}
@Test
public void openRanges() {
TimeRange one = new TimeRangeImpl(new MillisecondsTimePoint(0), null);
TimeRange two = create(5, 10);
TimeRange three = new TimeRangeImpl(null, new MillisecondsTimePoint(15));
assertTrue(two.liesWithin(one));
assertTrue(two.liesWithin(three));
assertTrue(one.intersects(three));
assertTrue(one.endsAfter(three));
assertFalse(one.startsBefore(three));
}
@Test
public void union() {
TimeRange one = create(5, 10);
TimeRange two = create(7, 12);
TimeRange union = one.union(two);
assertEquals(5, union.from().asMillis());
assertEquals(12, union.to().asMillis());
two = create(11, 16);
assertNull(one.union(two));
two = create(7, Long.MAX_VALUE);
union = two.union(one);
TimeRange union2 = one.union(two);
assertEquals(5, union.from().asMillis());
assertEquals(5, union2.from().asMillis());
assertEquals(Long.MAX_VALUE, union.to().asMillis());
assertEquals(Long.MAX_VALUE, union2.to().asMillis());
}
@Test
public void intersection() {
TimeRange one = create(5, 10);
TimeRange two = create(7, 12);
TimeRange intersection = one.intersection(two);
assertEquals(7, intersection.from().asMillis());
assertEquals(10, intersection.to().asMillis());
two = create(11, 16);
assertNull(one.intersection(two));
two = create(7, Long.MAX_VALUE);
intersection = two.intersection(one);
assertEquals(7, intersection.from().asMillis());
assertEquals(10, intersection.to().asMillis());
one = create(0, Long.MAX_VALUE);
two = create(Long.MIN_VALUE, 10);
intersection = two.intersection(one);
assertEquals(0, intersection.from().asMillis());
assertEquals(10, intersection.to().asMillis());
}
}