public void ResultsMatchingTest() { var cObject = new CalculateAvailabilityCase { Src = new ObservationTime { FullDayLeaves = new List <Interval <DateTime> >() { new Interval <DateTime> { Start = new DateTime(2018, 1, 1), End = new DateTime(2018, 1, 5) } }, ObservationInterval = new Interval <DateTime> { Start = new DateTime(2018, 1, 1), End = new DateTime(2018, 2, 1) }, WeekWorkingDays = defaultWorkingDays }, Result = new ExpectedResult <decimal> { ShouldFail = false, Value = 19 } }; var wObject = new ObserveWorkingTime { WeekWorkingDays = defaultWorkingDays, Leaves = new List <WorkingInterval> { new WorkingInterval(8) { Start = new DateTime(2018, 1, 1), End = new DateTime(2018, 1, 5) } }, ObservationInterval = new WorkingInterval(8) { Start = new DateTime(2018, 1, 1), End = new DateTime(2018, 2, 1) } }; TimeSpan result = TimeSpan.Zero; Assert.DoesNotThrow(() => result = Manager.WorkAvailability(wObject)); Assert.DoesNotThrow(() => Manager.CalculateAvailability(cObject.Src)); Assert.AreEqual(Manager.CalculateAvailability(cObject.Src).TotalDays, Manager.TimeSpanToWorkingDays(wObject.ObservationInterval.HoursPerDay, result)); }
/// <inheritdoc/> public TimeSpan WorkAvailability(ObserveWorkingTime observeWorkingTime) { TimeSpan step = TimeSpan.FromHours(24); var totalSpan = observeWorkingTime.ObservationInterval.End.Subtract(observeWorkingTime.ObservationInterval.Start).Ticks; long availableTicks = 0; DateTime iterationDate = observeWorkingTime.ObservationInterval.Start; if (step.Days > 1) { throw new ArgumentOutOfRangeException(nameof(step), "step should be less then a day in ticks"); } var modulo = totalSpan % step.Ticks; long totalMistake = 0; for (long i = 0; i < totalSpan; i = i + step.Ticks) { var isNewDay = iterationDate.AddTicks(step.Ticks).Date != iterationDate.Date || i == 0; iterationDate = iterationDate.AddTicks(step.Ticks); if (!isNewDay) { totalMistake = iterationDate.Date.AddDays(1).Ticks - iterationDate.Ticks + totalMistake; continue; } if (observeWorkingTime.WeekWorkingDays.All(it => it.Value != (int)iterationDate.DayOfWeek)) { continue; } //TODO: check for the crossing in dates. var leavesOnDate = observeWorkingTime.Leaves.Where(it => it.Start <= iterationDate && iterationDate <= it.End); if (leavesOnDate.Any()) { var leaveHoursSum = leavesOnDate.Sum(it => it.HoursPerDay); if (leaveHoursSum < observeWorkingTime.ObservationInterval.HoursPerDay) { availableTicks += TimeSpan.FromHours(Convert.ToDouble(observeWorkingTime.ObservationInterval.HoursPerDay - leaveHoursSum)).Ticks; } continue; } availableTicks += TimeSpan .FromHours(Convert.ToDouble(observeWorkingTime.ObservationInterval.HoursPerDay)).Ticks; } return(TimeSpan.FromTicks(availableTicks)); }