Я пытаюсь рассчитать срок действия соглашения об уровне обслуживания, и в то же время мне также необходимо вернуться к расчету соглашения об уровне обслуживания в другом направлении.
Я боролся с вычислениями за "рабочее время" (т.е. время, в течение которого работа возможна в течение нескольких дней), и решил использовать стороннюю библиотеку под названием TimePeriodLibrary.NET для задачи. Мне нужно сделать две вещи:
- При запуске
DateTime
иTimeSpan
вы должны получитьDateTime
, когда дата соглашения о уровне обслуживания является обязательной (с учетом даты). - Учитывая начало
DateTime
и конецDateTime
, вы должны получитьTimeSpan
того, как долго должно быть достигнуто соглашение об уровне обслуживания.
Весь исходный код (тестовый проект находится на GitHub). У меня есть класс ServiceLevelManager
, который выполняет всю работу. Он принимает список WorkDays
и HolidayPeriods
, чтобы определить, какие часы доступны для работы. Класс CalendarPeriodCollector
дает неожиданные результаты. Ожидания, которые работают при определении даты выполнения с временного интервала, не вычисляются правильно, когда я возвращаю их.
Может ли кто-нибудь увидеть, что я делаю что-то неправильно, или у библиотеки есть ошибка?
namespace ServicePlanner
{
using System;
using System.Collections.Generic;
using Itenso.TimePeriod;
public class ServicePlannerManager
{
public ServicePlannerManager(IEnumerable<WorkDay> workDays, IEnumerable<HolidayPeriod> holidays)
{
this.WorkDays = workDays;
this.Holidays = holidays;
}
public IEnumerable<WorkDay> WorkDays { get; set; }
public IEnumerable<HolidayPeriod> Holidays { get; set; }
public TimeSpan GetRemainingWorkingTime(DateTime start, DateTime dueDate)
{
var filter = new CalendarPeriodCollectorFilter();
foreach (var dayOfWeek in this.WorkDays)
{
filter.CollectingDayHours.Add(new DayHourRange(dayOfWeek.DayOfWeek, new Time(dayOfWeek.StartTime), new Time(dayOfWeek.EndTime)));
}
foreach (var holiday in this.Holidays)
{
filter.ExcludePeriods.Add(new TimeBlock(holiday.StartTime, holiday.EndTime));
}
var range = new CalendarTimeRange(start, dueDate);
var collector = new CalendarPeriodCollector(filter, range);
collector.CollectHours();
var duration = collector.Periods.GetTotalDuration(new TimeZoneDurationProvider(TimeZoneInfo.FindSystemTimeZoneById("UTC")));
return duration;
//var rounded = Math.Round(duration.TotalMinutes, MidpointRounding.AwayFromZero);
//return TimeSpan.FromMinutes(rounded);
}
}
}
Идентификаторы модулей, которые не выполняются, извлекаются ниже:
[TestFixture]
public class ServicePlannerManagerTest
{
[Test, TestCaseSource("LocalSource")]
public void GetRemainingWorkingTimeWithHolidayShouldOnlyEnumerateWorkingTime(DateTime startTime, TimeSpan workingHours, DateTime expectedDueDate, string expectation)
{
// Arrange
var workDays = new List<WorkDay>
{
new WorkDay(DayOfWeek.Monday, new DateTime(1, 1, 1, 9, 0, 0), new DateTime(1, 1, 1, 17, 0, 0)),
new WorkDay(DayOfWeek.Tuesday, new DateTime(1, 1, 1, 9, 0, 0), new DateTime(1, 1, 1, 17, 0, 0)),
new WorkDay(DayOfWeek.Wednesday, new DateTime(1, 1, 1, 9, 0, 0), new DateTime(1, 1, 1, 17, 0, 0)),
new WorkDay(DayOfWeek.Thursday, new DateTime(1, 1, 1, 9, 0, 0), new DateTime(1, 1, 1, 17, 0, 0)),
new WorkDay(DayOfWeek.Friday, new DateTime(1, 1, 1, 9, 0, 0), new DateTime(1, 1, 1, 17, 0, 0)),
};
var holidayPeriods = new List<HolidayPeriod>
{
new HolidayPeriod(new DateTime(2015, 9, 15, 00, 0, 0), new DateTime(2015, 9, 16, 0, 0, 0))
};
var service = new ServicePlannerManager(workDays, holidayPeriods);
// Act
var result = service.GetRemainingWorkingTime(startTime, expectedDueDate);
// Assert -
Assert.AreEqual(workingHours.TotalHours, result.TotalHours, expectation);
}
protected IEnumerable LocalSource()
{
yield return
new TestCaseData(
new DateTime(2015, 9, 14, 9, 0, 0),
new TimeSpan(23, 0, 0),
new DateTime(2015, 9, 17, 16, 0, 0),
"5. Expected 23 hours of working time to end on the 17/09/2015 16:00. Monday to Thursday evening. Just short of 3 full working days by one hour. Tuesday is holiday.");
}
}
Результат этого теста
5. Expected 23 hours of working time to end on the 17/09/2015 16:00. Monday to Thursday evening. Just short of 3 full working days by one hour. Tuesday is holiday.
Expected: 23.0d
But was: 15.999999999944444d
Я хочу знать, неправильно ли я использую сборщик или если у сборщика есть ошибка.