diff --git a/src/main/java/net/fortuna/ical4j/model/TemporalAmountComparator.java b/src/main/java/net/fortuna/ical4j/model/TemporalAmountComparator.java new file mode 100644 index 000000000..542983ba2 --- /dev/null +++ b/src/main/java/net/fortuna/ical4j/model/TemporalAmountComparator.java @@ -0,0 +1,54 @@ +package net.fortuna.ical4j.model; + +import java.time.Duration; +import java.time.Period; +import java.time.temporal.TemporalAmount; +import java.util.Comparator; + +public class TemporalAmountComparator implements Comparator { + @Override + public int compare(TemporalAmount o1, TemporalAmount o2) { + int result = 0; + if (!o1.getClass().equals(o2.getClass())) { +// throw new UnsupportedOperationException("Unable to compare different Temporal types"); + boolean o1datebased = o1.getUnits().stream().anyMatch(u -> u.isDateBased()); + boolean o2datebased = o2.getUnits().stream().anyMatch(u -> u.isDateBased()); + if (o1datebased != o2datebased) { + if (o1datebased) { + result = Integer.MAX_VALUE; + } else { + result = Integer.MIN_VALUE; + } + } + } else if (o1 instanceof Period && o2 instanceof Period) { + Period p1 = (Period) o1, p2 = (Period) o2; + if (p1.isNegative() != p2.isNegative()) { + if (p1.isNegative()) { + result = Integer.MIN_VALUE; + } + else { + result = Integer.MAX_VALUE; + } + } + else if (p1.getYears() != p2.getYears()) { + result = p1.getYears() - p2.getYears(); + } + else if (p1.getMonths() != p2.getMonths()) { + result = p1.getMonths() - p2.getMonths(); + } + else { + result = p1.getDays() - p2.getDays(); + } + // invert sense of all tests if both durations are negative + if (p1.isNegative()) { + return -result; + } + else { + return result; + } + } else { + result = Duration.from(o1).compareTo(Duration.from(o2)); + } + return result; + } +} diff --git a/src/test/groovy/net/fortuna/ical4j/model/TemporalAmountComparatorTest.groovy b/src/test/groovy/net/fortuna/ical4j/model/TemporalAmountComparatorTest.groovy new file mode 100644 index 000000000..4af115af7 --- /dev/null +++ b/src/test/groovy/net/fortuna/ical4j/model/TemporalAmountComparatorTest.groovy @@ -0,0 +1,24 @@ +package net.fortuna.ical4j.model + +import spock.lang.Specification + +import java.time.Duration + +class TemporalAmountComparatorTest extends Specification { + + TemporalAmountComparator comparator = [] + + def 'assert comparison is correct'() { + expect: + comparator.compare(o1, o2) == expectedResult + + where: + o1 | o2 | expectedResult + Duration.ofDays(1) | Duration.ofDays(2) | -1 + Duration.ofHours(-2) | Duration.ofHours(2) | -1 + java.time.Period.ofDays(3) | java.time.Period.ofDays(2) | 1 + java.time.Period.ofMonths(12) | java.time.Period.ofYears(1) | -1 + java.time.Period.ofMonths(12) | java.time.Period.ofMonths(12) | 0 + java.time.Period.ofDays(1) | java.time.Duration.ofDays(1) | Integer.MAX_VALUE + } +}