public void ThenShouldReportAtTheGrainRequested(AvailabilityTimeUnit timeUnit) { // arrange var mySchedules = new List <Schedule>(); var startDate = new DateTime(2019, 7, 14); var endDate = new DateTime(2019, 7, 20); byte startHour = 8; byte endHour = 17; // act var results = new SCHEDULING.ScheduleManager().CalculateAvailability(mySchedules, startDate, endDate, startHour, endHour, timeUnit); // assert var expectedResults = new Dictionary <AvailabilityTimeUnit, int> { { AvailabilityTimeUnit.HalfHour, 126 }, { AvailabilityTimeUnit.Hour, 63 }, { AvailabilityTimeUnit.Day, 7 } }; Assert.Equal(expectedResults[timeUnit], results.Count()); }
public IEnumerable <TimeSlotAvailability> CalculateAvailability(List <Schedule> mySchedules, DateTime startDate, DateTime endDate, byte startHour, byte endHour, AvailabilityTimeUnit grain) { var workingTimeSlots = new ConcurrentBag <TimeSlot>(); var startDateTime = startDate.Date.AddHours(startHour); var endDateTime = endDate.Date; Parallel.ForEach(mySchedules, s => { var theseTimeSlots = ExpandSchedule(s, startDateTime, endDateTime); foreach (var ts in theseTimeSlots) { workingTimeSlots.Add(ts); } }); var outAvailability = new List <TimeSlotAvailability>(); var timeStep = TimeSpan.FromMinutes((int)grain); if (grain == AvailabilityTimeUnit.Day) { timeStep = TimeSpan.FromHours(endHour - startHour); } for (var dateCounter = 0; dateCounter <= endDate.Date.Subtract(startDate.Date).Days; dateCounter++) { for (var timeCounter = TimeSpan.FromHours(startHour); timeCounter < TimeSpan.FromHours(endHour); timeCounter = timeCounter.Add(timeStep)) { var thisAvailability = new TimeSlotAvailability() { StartDateTime = startDate.Date.AddDays(dateCounter).Add(timeCounter), EndDateTime = startDate.Date.AddDays(dateCounter).Add(timeCounter).Add(timeStep), Count = 0 }; // CALCULATE thisAvailability.Count = workingTimeSlots .Count(t => t.Overlaps(thisAvailability) && t.Status == ScheduleStatus.Available); outAvailability.Add(thisAvailability); } } return(outAvailability); }