The Timetool component generates an incorrect week at the beginning of the year. This error propagates to the GetPrevWeek() function, ultimately causing the CalendarDateAdd.Subtract method to return inaccurate results. A unit test demonstrating this issue has been included to facilitate debugging.
[Trait("Category", "CalendarDateAdd")]
[Fact]
public void WorkHoursWithHolidayTest()
{
var calendarDateAdd = new CalendarDateAdd();
calendarDateAdd.AddWorkingWeekDays();
calendarDateAdd.WeekDays.Add(DayOfWeek.Saturday);
// Holidays
calendarDateAdd.ExcludePeriods.Add(new Day(2025, 12, 24, calendarDateAdd.Calendar));
calendarDateAdd.ExcludePeriods.Add(new Day(2025, 12, 25, calendarDateAdd.Calendar));
calendarDateAdd.ExcludePeriods.Add(new Day(2025, 12, 26, calendarDateAdd.Calendar));
// Define Working Hours
calendarDateAdd.WorkingDayHours.Add(new DayHourRange(DayOfWeek.Monday, 09, 16));
calendarDateAdd.WorkingDayHours.Add(new DayHourRange(DayOfWeek.Tuesday, 09, 16));
calendarDateAdd.WorkingDayHours.Add(new DayHourRange(DayOfWeek.Wednesday, 09, 16));
calendarDateAdd.WorkingDayHours.Add(new DayHourRange(DayOfWeek.Thursday, 09, 16));
calendarDateAdd.WorkingDayHours.Add(new DayHourRange(DayOfWeek.Friday, 09, 16));
calendarDateAdd.WorkingDayHours.Add(new DayHourRange(DayOfWeek.Saturday, 09, 16));
// Example setup of having the end time and wanting to backwards schedule to calculate a start time.
// End Time: 1/2/2025 4:00:00 PM
// Time Span: 21 hours
// Start Time: Should be 12/31/2024 9:00:00 AM
DateTime endTime = new DateTime(2025, 1, 2, 16, 0, 0);
TimeSpan timeSpan = new TimeSpan(21, 0, 0);
DateTime? startTime = calendarDateAdd.Subtract(endTime, timeSpan);
Assert.True(endTime > startTime);
Assert.Equal(startTime, new DateTime(2024, 12, 31, 9, 0, 0));
// Breakdown of the error:
// In case its living location dependent my ITimeCalendar is set to culture = en-US, first day of week = Sunday
// 1. Timetool attempts to calculate Week({1/2/2025 4:00:00 PM}) in which it returns {w/c 1 2025; 1/1/2025 - 1/8/2025 | 7.00:00}
// 2. Timespan is not 0 so it will call GetPreviousWeek({w/c 1 2025; 1/1/2025 - 1/8/2025 | 7.00:00})
// 3. This will then call Week({12/31/2024 11:59:59 PM}) which returns previous week of {w/c 53 2024; 12/29/2024 - 1/4/2025 | 6.23:59}
// 4. Will then consume the rest of timespan returning a startTime of 1/3/2025 4:00:00 PM
// One major concern here is that you are expecting a value less than 1/2/2025 4:00:00 PM but are receiving a value that is greater than.
// In your code if your not checking for this and just plug it into a CalendarTimeRange, it wont show any errors. TimeRange will flip the start and end.
// Easy to go unnoticed unless you put error check in your code to validate your TimePeriodCollections
// What went wrong?
// 1. At the very start if we want the Week({1/2/2025 4:00:00 PM}) it should be 12/29/2024 - 1/4/2025. It stops short on Jan 1, 2025, even though first day of week is Sunday.
// 2. Notice too that when 12/31/2024 is fed into Week() it is able to correectly grab the week its contained in.
// Note* Im not too sure if by these calendar setting if {w/c 53 2024; 12/29/2024 - 1/4/2025 | 6.23:59} is supposed to be the 53rd week of 2024 or if it should be the 1st week of 2025.
} // WorkHoursWithHolidayTest
The Timetool component generates an incorrect week at the beginning of the year. This error propagates to the GetPrevWeek() function, ultimately causing the CalendarDateAdd.Subtract method to return inaccurate results. A unit test demonstrating this issue has been included to facilitate debugging.