xiaoyi
3 天以前 b5e1bceabb36fe1d1e5e88397280d12e7044c6dd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package cn.iocoder.yudao.module.mes.service.collect;
 
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
 
/** 根据采样间隔推算离线区间,不推断首次采样之前的状态。 */
final class CollectOfflinePolicy {
    record Interval(LocalDateTime start, LocalDateTime end) {}
 
    private CollectOfflinePolicy() {}
 
    static List<Interval> calculate(List<LocalDateTime> samples, LocalDateTime start,
                                    LocalDateTime end, Duration timeout) {
        if (start == null || end == null || !start.isBefore(end) || timeout == null || timeout.isNegative() || timeout.isZero()) {
            throw new IllegalArgumentException("时间范围或离线阈值无效");
        }
        List<LocalDateTime> ordered = samples.stream().filter(t -> t != null && !t.isAfter(end)).distinct().sorted().toList();
        List<Interval> result = new ArrayList<>();
        for (int i = 0; i < ordered.size(); i++) {
            LocalDateTime offline = ordered.get(i).plus(timeout);
            LocalDateTime recovery = i + 1 < ordered.size() ? ordered.get(i + 1) : end;
            LocalDateTime clippedStart = offline.isBefore(start) ? start : offline;
            LocalDateTime clippedEnd = recovery.isAfter(end) ? end : recovery;
            if (clippedStart.isBefore(clippedEnd)) result.add(new Interval(clippedStart, clippedEnd));
        }
        return result;
    }
}