排除重叠时间的日期区间数组持续时间

3
我正在尝试从HealthKit数据中计算睡眠时长。对于睡眠,HealthKit返回来自不同来源的所有样本,即使这些样本有重叠。(与步数等事物不同,您可以使用HKStatisticsQuery并且它会为您去重数据)。
每个样本都包含开始和结束日期。我将这些起始/结束日期放入[DateInterval]数组中,其结果如下所示(时间以秒为单位)。
start 2020-08-26 02:55:00 +0000 end 2020-08-26 03:00:00 +0000 time 300.0
start 2020-08-26 03:40:00 +0000 end 2020-08-26 05:00:00 +0000 time 4800.0
start 2020-08-26 05:15:00 +0000 end 2020-08-26 07:15:00 +0000 time 7200.0
start 2020-08-26 07:25:00 +0000 end 2020-08-26 08:00:00 +0000 time 2100.0
start 2020-08-26 08:10:00 +0000 end 2020-08-26 08:50:00 +0000 time 2400.0
start 2020-08-26 03:05:45 +0000 end 2020-08-26 11:51:47 +0000 time 31562.0
start 2020-08-26 11:51:50 +0000 end 2020-08-26 11:51:53 +0000 time 3.0
start 2020-08-26 12:10:39 +0000 end 2020-08-26 12:10:40 +0000 time 1.0

我需要一种算法或某种逻辑,它不会重复睡眠时间。在这个例子中,将所有时间间隔的持续时间相加得到13小时26分钟。去重后,它应该加起来是8小时51分钟(根据健康应用程序显示的内容)。


根据开始日期对日期间隔进行排序。然后,如果它们重叠,将每个间隔与其后继间隔连接起来。 - undefined
1个回答

5

我没有进行完整的测试,但你可以理解一下。对它们进行排序并跳过重叠的部分。

 func calculateSpentTime(for intervals: [DateInterval]) -> TimeInterval {  
    guard intervals.count > 1 else {
        return intervals.first?.duration ?? 0
    }
    
    let sorted = intervals.sorted { $0.start < $1.start }
    
    var total: TimeInterval = 0
    var start = sorted[0].start
    var end = sorted[0].end
    
    for i in 1..<sorted.count {
        
        if sorted[i].start > end {
            total += end.timeIntervalSince(start)
            start = sorted[i].start
            end = sorted[i].end
        } else if sorted[i].end > end {
            end = sorted[i].end
        }
    }
    
    total += end.timeIntervalSince(start)
    return total
}

我需要使用更具体的情况来进行测试,但似乎这确实给我了正确的结果! - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接