Mój pomysł to wygenerowanie unikalnych punktów czasowych, a następnie sprawdzenie czy odcinki czasu się w nich kończące są w którymkolwiek z przedziałów.
Implementacja w Javie, kod sklecony na kolanie, proszę nie rzucać kamieniami, to jest tylko proof of concept.
Nie wykluczam, że mogą być jakieś dziury w rozumowaniu.
package timeseries;
import java.time.Duration;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.lang3.tuple.Pair;
public class TimeSeries {
public static void main(String[] args) {
List<Pair<LocalTime, LocalTime>> ranges = new ArrayList<>();
// LocalTime now = LocalTime.now();
// Pair<LocalTime, LocalTime> range = Pair.of(now, now.plusMinutes(6));
// Random prng = new Random(42);
// int n = 3;
// for (int i = 0; i < n; i++) {
// ranges.add(Pair.of(now.minusMinutes(prng.nextInt(5)), now.plusMinutes(prng.nextInt(6))));
// }
//40
ranges.add(Pair.of(LocalTime.of(8, 10), LocalTime.of(8, 50)));
ranges.add(Pair.of(LocalTime.of(8, 12), LocalTime.of(8, 48)));
//20
ranges.add(Pair.of(LocalTime.of(9, 10), LocalTime.of(9, 20)));
ranges.add(Pair.of(LocalTime.of(9, 20), LocalTime.of(9, 30)));
//20
ranges.add(Pair.of(LocalTime.of(10, 15), LocalTime.of(10, 25)));
ranges.add(Pair.of(LocalTime.of(10, 35), LocalTime.of(10, 45)));
//20+20
ranges.add(Pair.of(LocalTime.of(11, 00), LocalTime.of(11, 13)));
ranges.add(Pair.of(LocalTime.of(11, 00), LocalTime.of(11, 20)));
ranges.add(Pair.of(LocalTime.of(12, 40), LocalTime.of(13, 00)));
ranges.add(Pair.of(LocalTime.of(12, 45), LocalTime.of(13, 00)));
//
Function<LocalTime, Integer> mapper = ti -> (int) Duration.between(LocalTime.of(0, 0), ti).toMinutes();
List<Integer> uniqueHours = ranges.stream()
.flatMap(pair -> Stream.of(pair.getLeft(), pair.getRight()))
.map(mapper)
.distinct()
.sorted()
.collect(Collectors.toList());
List<Pair<Integer, Integer>> rangesInt = ranges.stream()
.map(pair -> Pair.of(mapper.apply(pair.getLeft()), mapper.apply(pair.getRight())))
.collect(Collectors.toList());
System.out.println(ranges);
System.out.println(rangesInt);
System.out.println(uniqueHours);
int total = 0;
for (int i = 1; i < uniqueHours.size(); i++) {
int s = uniqueHours.get(i - 1);
int e = uniqueHours.get(i);
int diff = e - s;
int sFinal = s;
int eFinal = e;
boolean inside = rangesInt.stream().anyMatch(pair -> pair.getLeft() <= sFinal && pair.getRight() >= eFinal);
if (inside) {
total += diff;
}
System.out.println(String.format(
"Czy przedział %02d:%02d do %02d:%02d == %03d jest objęty czasem: %s (total: %03d)",
(s / 60),
(s % 60),
(e / 60),
(e % 60),
diff,
(inside ? "tak" : "nie"),
total));
}
System.out.println(total);
}
}
[(08:10,08:50), (08:12,08:48), (09:10,09:20), (09:20,09:30), (10:15,10:25), (10:35,10:45), (11:00,11:13), (11:00,11:20), (12:40,13:00), (12:45,13:00)]
[(490,530), (492,528), (550,560), (560,570), (615,625), (635,645), (660,673), (660,680), (760,780), (765,780)]
[490, 492, 528, 530, 550, 560, 570, 615, 625, 635, 645, 660, 673, 680, 760, 765, 780]
Czy przedział 08:10 do 08:12 == 002 jest objęty czasem: tak (total: 002)
Czy przedział 08:12 do 08:48 == 036 jest objęty czasem: tak (total: 038)
Czy przedział 08:48 do 08:50 == 002 jest objęty czasem: tak (total: 040)
Czy przedział 08:50 do 09:10 == 020 jest objęty czasem: nie (total: 040)
Czy przedział 09:10 do 09:20 == 010 jest objęty czasem: tak (total: 050)
Czy przedział 09:20 do 09:30 == 010 jest objęty czasem: tak (total: 060)
Czy przedział 09:30 do 10:15 == 045 jest objęty czasem: nie (total: 060)
Czy przedział 10:15 do 10:25 == 010 jest objęty czasem: tak (total: 070)
Czy przedział 10:25 do 10:35 == 010 jest objęty czasem: nie (total: 070)
Czy przedział 10:35 do 10:45 == 010 jest objęty czasem: tak (total: 080)
Czy przedział 10:45 do 11:00 == 015 jest objęty czasem: nie (total: 080)
Czy przedział 11:00 do 11:13 == 013 jest objęty czasem: tak (total: 093)
Czy przedział 11:13 do 11:20 == 007 jest objęty czasem: tak (total: 100)
Czy przedział 11:20 do 12:40 == 080 jest objęty czasem: nie (total: 100)
Czy przedział 12:40 do 12:45 == 005 jest objęty czasem: tak (total: 105)
Czy przedział 12:45 do 13:00 == 015 jest objęty czasem: tak (total: 120)
120