举例 1.2-1.5 , 1.4-1.6
去重后就是 1.2 1.3 1.4 1.5 .16 一共5天
function getDays (ranges: readonly (readonly [number, number])[]): number {
const days = new Set<number>();
for (const [start, end] of ranges) {
for (let time = start; end >= time; time += 8.64e7) {
days.add(time);
}
}
return days.size;
}
getDays([
[Date.parse("2021-01-02"), Date.parse("2021-01-05")],
[Date.parse("2021-01-04"), Date.parse("2021-01-06")],
]);
###把时间看成数轴,其实这就是两个区间的相对位置;要么有区间重叠,时间就是最小值到最大值的天数;
要么不重叠,各自区间相减的和 就是最后结果
Python version:
# 设一个包含重复和不重复起止日期的列表
# 可知2021-01-02 ~ 2021-01-06 共5天(含头尾)。
# 2021-01-09 到2021-01-12 共4天(含头尾)
# 总天数为9天
date_list = [('2021-01-04','2021-01-06'),('2021-01-02','2021-01-05'),('2021-01-09','2021-01-12')]
# 先转换成日期对象以便比较大小和算术运算
# 并进行排序,保证每一组开始日期都是比下一组要小
date_list = sorted([(datetime.strptime(i,'%Y-%m-%d'),datetime.strptime(j,'%Y-%m-%d')) for i,j in date_list])
# 总天数
length_of_dates = 0
#从第一组日期到倒数第二组日期进行循环
for i in range(len(date_list)-1):
# 如果当前结束如期比下一个起始日期小,则没有重叠:
# 完整天数则是当前结束日期-当前开始日期+1天
if date_list[i][1] < date_list[i+1][0]:
length_of_dates += (date_list[i][1] - date_list[i][0]).days +1
# 如果当前结束日期比下一个起始日期大
# 则只增加当前起始日期到下一个起始日期的天数。
else:
length_of_dates += (date_list[i+1][0] - date_list[i][0]).days
# 补上最后一组日期的天数
length_of_dates += (date_list[-1][1] - date_list[-1][0]).days + 1
# 结果
print(length_of_dates) # 9