subtract method
Returns a list of Periods that are the difference between this Period
and the periods
passed as argument.
The periods
are sorted, merged, trimmed and if not overlapping with
this Period they are removed.
After that, the result will be the periods between the merged periods and
the period between the start of this Period and the first merged
period, and the period between the end of this Period and the last
merged period.
If the periods
are overlapping with this Period the result will be
a list with only this Period.
Example:
final period = Period(
start: DateTime(2020, 1, 1),
end: DateTime(2020, 1, 31),
);
final periods = [
Period(
start: DateTime(2020, 1, 1),
end: DateTime(2020, 1, 10),
),
Period(
start: DateTime(2020, 1, 15),
end: DateTime(2020, 1, 20),
),
Period(
start: DateTime(2020, 1, 25),
end: DateTime(2020, 1, 29),
),
];
final result = period.subtract(periods);
// result = [
// Period(
// start: DateTime(2020, 1, 10),
// end: DateTime(2020, 1, 15),
// ),
// Period(
// start: DateTime(2020, 1, 20),
// end: DateTime(2020, 1, 25),
// ),
// Period(
// start: DateTime(2020, 1, 29),
// end: DateTime(2020, 1, 31),
// ),
// ]
Implementation
List<Period> subtract(List<Period> periods) {
if (periods.isEmpty) return [this];
final localPeriods = trim(periods);
if (localPeriods.isEmpty) return [this];
final merged = mergeOverlappingPeriods(localPeriods);
final result = <Period>[];
final difference = calculateStartDifference(merged.first, this);
if (difference != null) result.add(difference);
for (var i = 0, j = 1; j < merged.length; i++, j++) {
result.add(Period.inBetween(merged[i], merged[j])!);
}
if (merged.length > 1) {
final differenceLast = calculateEndDifference(merged.last, this);
if (differenceLast != null) result.add(differenceLast);
}
return result;
}