c# - 计算日期时间列表中的总分钟数
问题描述
我有约会课程的清单。在下面的代码中;
- 约会1,约会2和约会3相交。
- 约会4 和约会5 相交。
- 约会6不相交
- 约会1,约会2和约会3开始日期时间为'2018-07-10 08:00:00',完成日期时间为'2018-07-10 12:00:00',总时间为4小时。
- 约会4和约会5开始日期时间是'2018-07-10 14:00:00',完成日期时间是'2018-07-10 17:00:00',总时间是3小时。
- 和约会 6 是不相交的,这里是 1 小时。
总时间为4+3+1=8,
我如何在给定的约会日期时间值中找到 8。
class Program
{
static void Main(string[] args)
{
List<Appointment> appointments = new List<Appointment>();
Appointment appointment1 = new Appointment();
appointment1.StartDate = new DateTime(2018, 07, 11, 08, 00, 00);
appointment1.FinishDate = new DateTime(2018, 07, 11, 11, 00, 00);
Appointment appointment2 = new Appointment();
appointment2.StartDate = new DateTime(2018, 07, 11, 10, 00, 00);
appointment2.FinishDate = new DateTime(2018, 07, 11, 12, 00, 00);
Appointment appointment3 = new Appointment();
appointment3.StartDate = new DateTime(2018, 07, 11, 09, 00, 00);
appointment3.FinishDate = new DateTime(2018, 07, 11, 12, 00, 00);
Appointment appointment4 = new Appointment();
appointment4.StartDate = new DateTime(2018, 07, 11, 14, 00, 00);
appointment4.FinishDate = new DateTime(2018, 07, 11, 16, 00, 00);
Appointment appointment5 = new Appointment();
appointment5.StartDate = new DateTime(2018, 07, 11, 15, 00, 00);
appointment5.FinishDate = new DateTime(2018, 07, 11, 17, 00, 00);
Appointment appointment6 = new Appointment();
appointment6.StartDate = new DateTime(2018, 07, 11, 18, 00, 00);
appointment6.FinishDate = new DateTime(2018, 07, 11, 19, 00, 00);
appointments.Add(appointment1);
appointments.Add(appointment2);
appointments.Add(appointment3);
appointments.Add(appointment4);
appointments.Add(appointment5);
appointments.Add(appointment6);
Console.ReadLine();
}
}
public class Appointment
{
public DateTime StartDate { get; set; }
public DateTime FinishDate { get; set; }
}
解决方案
您首先需要合并重叠时间,然后对时间跨度求和:
void Main()
{
List<Appointment> appointments = new List<Appointment>();
Appointment appointment1 = new Appointment();
appointment1.StartDate = new DateTime(2018, 07, 11, 08, 00, 00);
appointment1.FinishDate = new DateTime(2018, 07, 11, 11, 00, 00);
Appointment appointment2 = new Appointment();
appointment2.StartDate = new DateTime(2018, 07, 11, 10, 00, 00);
appointment2.FinishDate = new DateTime(2018, 07, 11, 12, 00, 00);
Appointment appointment3 = new Appointment();
appointment3.StartDate = new DateTime(2018, 07, 11, 09, 00, 00);
appointment3.FinishDate = new DateTime(2018, 07, 11, 12, 00, 00);
Appointment appointment4 = new Appointment();
appointment4.StartDate = new DateTime(2018, 07, 11, 14, 00, 00);
appointment4.FinishDate = new DateTime(2018, 07, 11, 16, 00, 00);
Appointment appointment5 = new Appointment();
appointment5.StartDate = new DateTime(2018, 07, 11, 15, 00, 00);
appointment5.FinishDate = new DateTime(2018, 07, 11, 17, 00, 00);
Appointment appointment6 = new Appointment();
appointment6.StartDate = new DateTime(2018, 07, 11, 18, 00, 00);
appointment6.FinishDate = new DateTime(2018, 07, 11, 19, 00, 00);
appointments.Add(appointment1);
appointments.Add(appointment2);
appointments.Add(appointment3);
appointments.Add(appointment4);
appointments.Add(appointment5);
appointments.Add(appointment6);
var ranges = appointments.Select(a => new Range {Start=a.StartDate, End=a.FinishDate});
var total = MergeTimes(ranges).Sum(a => (a.End-a.Start).TotalHours);
Console.WriteLine(total);
}
public class Appointment
{
public DateTime StartDate { get; set; }
public DateTime FinishDate { get; set; }
}
public class Range
{
public DateTime Start {get;set;}
public DateTime End {get;set;}
}
public IEnumerable<Range> MergeTimes(IEnumerable<Range> times)
{
if (times.Count() == 0)
{
return times;
}
Range[] orderedTimes = (from t in times
orderby t.Start
select t).ToArray();
List<Range> merged = new List<Range>();
Range current = new Range
{
Start = orderedTimes[0].Start,
End = orderedTimes[0].End
};
for (int i = 0; i < orderedTimes.Length; i++)
{
if (current.Start <= orderedTimes[i].End && current.End >= orderedTimes[i].Start)
{
current.Start = ((current.Start < orderedTimes[i].Start) ? current.Start : orderedTimes[i].Start);
current.End = ((current.End > orderedTimes[i].End) ? current.End : orderedTimes[i].End);
}
else
{
merged.Add(new Range
{
Start = current.Start,
End = current.End
});
current = new Range
{
Start = orderedTimes[i].Start,
End = orderedTimes[i].End
};
}
}
merged.Add(new Range
{
Start = current.Start,
End = current.End
});
return merged;
}
推荐阅读
- angular - 服务工作者获取新版本时显示加载屏幕
- sql - Vertica REFRESH_COLUMNS 失败并出现“Join inner did not fit in memory”错误
- javascript - 正则表达式仅获取 javascript 中的最后 N 个数字
- c# - 在 Linq 查询中返回空的可枚举作为属性会导致错误
- django - Django 项目中配置错误的自定义 HTTP 错误模板 (404,500)
- python - MongoDB与Python,用于存储游戏的用户名和密码
- jenkins - Jenkins用不同的参数一一运行作业
- mongodb - $lookup : 计算的foreinField 解决方法?
- java - 从 Callable 创建一个 HashMap 键
- spring - 将数据流映射到页面