using System.Collections.Generic;
using System.Threading.Tasks;
var rules = new List<breakpromisepunishrule>
new breakpromisepunishrule { breakPromiseTimes = 1, punishDays = 3 },
new breakpromisepunishrule { breakPromiseTimes = 2, punishDays = 5 },
new breakpromisepunishrule { breakPromiseTimes = 3, punishDays = 7 }
foreach (var item in rules)
Console.WriteLine($"规则:次数{item.breakPromiseTimes} 惩罚天数{item.punishDays}");
var absenceRecords = new List<DateTime>
var penaltyIntervals = CalculatePenalty(absenceRecords, rules);
var penaltyIntervals2 = MergeTimeSlot(penaltyIntervals);
penaltyIntervals = MergeTimeSlot(penaltyIntervals);
foreach (var item in absenceRecords)
Console.WriteLine($"爽约时间:{item}");
foreach (var interval in penaltyIntervals)
Console.WriteLine($"惩罚区间:{interval.startOfSlot.ToString("yyyy-MM-dd")} ~ {interval.endOfSlot.ToString("yyyy-MM-dd")}");
foreach (var item2 in penaltyIntervals2)
Console.WriteLine($"归并后惩罚区间:{item2.startOfSlot.ToString("yyyy-MM-dd")} ~ {item2.endOfSlot.ToString("yyyy-MM-dd")}");
absenceRecords = new List<DateTime>
new DateTime(2024, 1, 1),
new DateTime(2024, 1, 2),
penaltyIntervals = CalculatePenalty(absenceRecords, rules);
foreach (var item in absenceRecords)
Console.WriteLine($"爽约时间:{item}");
foreach (var interval in penaltyIntervals)
Console.WriteLine($"惩罚区间:{interval.startOfSlot.ToString("yyyy-MM-dd")} ~ {interval.endOfSlot.ToString("yyyy-MM-dd")}");
penaltyIntervals2 = MergeTimeSlot(penaltyIntervals);
foreach (var item2 in penaltyIntervals2)
Console.WriteLine($"归并后惩罚区间:{item2.startOfSlot.ToString("yyyy-MM-dd")} ~ {item2.endOfSlot.ToString("yyyy-MM-dd")}");
absenceRecords = new List<DateTime>
new DateTime(2024, 1, 1),
new DateTime(2024, 1, 2),
new DateTime(2024, 1, 3),
penaltyIntervals = CalculatePenalty(absenceRecords, rules);
foreach (var item in absenceRecords)
Console.WriteLine($"爽约时间:{item}");
foreach (var interval in penaltyIntervals)
Console.WriteLine($"惩罚区间:{interval.startOfSlot.ToString("yyyy-MM-dd")} ~ {interval.endOfSlot.ToString("yyyy-MM-dd")}");
penaltyIntervals2 = MergeTimeSlot(penaltyIntervals);
foreach (var item2 in penaltyIntervals2)
Console.WriteLine($"归并后惩罚区间:{item2.startOfSlot.ToString("yyyy-MM-dd")} ~ {item2.endOfSlot.ToString("yyyy-MM-dd")}");
public static List<TimeSlot> CalculatePenalty(List<DateTime> absenceRecords,List<breakpromisepunishrule> rules)
var penaltyIntervals = new List<TimeSlot>();
if (absenceRecords==null||rules==null||!absenceRecords.Any()||!rules.Any())
return new List<TimeSlot>();
rules = rules.OrderBy(c => c.breakPromiseTimes).ToList();
absenceRecords= absenceRecords.OrderBy(c=>c).ToList();
var startDate = DateTime.MinValue;
var endDate = DateTime.MinValue;
foreach (var record in absenceRecords)
var rule = new breakpromisepunishrule();
rule = rules.LastOrDefault();
rule = rules.FirstOrDefault(c => c.breakPromiseTimes == count);
endDate = record.AddDays((int)rule.punishDays - 1);
penaltyIntervals.Add(new TimeSlot { startOfSlot = record, endOfSlot = endDate });
public static List<TimeSlot> MergeTimeSlot(List<TimeSlot> timeSlots)
if (timeSlots == null || timeSlots.Count == 0)
return new List<TimeSlot>();
timeSlots.Sort((x, y) => x.startOfSlot.CompareTo(y.startOfSlot));
List<TimeSlot> mergedTimeSlots = new List<TimeSlot>();
TimeSlot currentSlot = timeSlots[0];
foreach (var slot in timeSlots)
if (slot.startOfSlot <= currentSlot.endOfSlot)
currentSlot.endOfSlot = (slot.endOfSlot > currentSlot.endOfSlot) ? slot.endOfSlot : currentSlot.endOfSlot;
mergedTimeSlots.Add(currentSlot);
mergedTimeSlots.Add(currentSlot);
public DateTime startOfSlot { get; set; }
public DateTime endOfSlot { get; set; }
public partial class breakpromisepunishrule
public long breakPromiseTimes { get; set; }
public long punishDays { get; set; }