PrintShiftInstances exception - end.earlier.than.start
Closed this issue · 11 comments
Hello,
I would like to thank you for this awesome library first.
I tried to analyze why my schedule settings not working as I expected.
I need two twelve hours shifts - day & night, four teams 24/7 (see picture)
I configured my schedule like this:
` _workSchedule = new WorkSchedule(scheduleName, description);
// Day shift, starts at 06:00 for 12 hours
Shift day = _workSchedule.CreateShift("Day", "Day shift", new LocalTime(6, 0, 0), Duration.FromHours(12));
// Night shift, starts at 18:00 for 12 hours
Shift night = _workSchedule.CreateShift("Night", "Night shift", new LocalTime(18, 0, 0), Duration.FromHours(12));
// rotation
Rotation rotation = _workSchedule.CreateRotation("My rotation",
"description..");
rotation.AddSegment(day, 2, 2);
rotation.AddSegment(night, 3, 2);
rotation.AddSegment(day, 2, 3);
rotation.AddSegment(night, 2, 2);
rotation.AddSegment(day, 3, 2);
rotation.AddSegment(night, 2, 3);
// reference date for start of shift rotations
LocalDate referenceDate = new LocalDate(2019, 1, 7);
_workSchedule.CreateTeam("Blue", "First team", rotation, referenceDate);
_workSchedule.CreateTeam("Yellow", "Second team", rotation, referenceDate.PlusDays(14));
_workSchedule.CreateTeam("Red", "Third team", rotation, referenceDate.PlusDays(21));
_workSchedule.CreateTeam("Green", "Fourth team", rotation, referenceDate.PlusDays(7));`
Problem was when I tried 04.02.2019 1:55 - I expected that output will be Red team..But result was Blue team.. So I wanted to analyse reason. I tried to use _workSchedule.PrintShiftInstances()
, but exception was returned (ex. key = end.earlier.than.start). Reason for this exception was that start.CompareTo()
returned -1
if (start.CompareTo(end) < 0) { string msg = String.Format(WorkSchedule.GetMessage("end.earlier.than.start"), start, end); throw new Exception(msg); }
I used this variables as parameters for compareTo method:
LocalDate start = new LocalDate(2019, 1, 9); LocalDate end = new LocalDate(2019, 2, 28);
I also check unit testing project but testToString is disabled (I tried TestDupont)
testToString = false;
Could you help me what's wrong please?
Thank you.
Should I create simple C# example which causing me probles or you don't have IDE for C# anymore?
I think I made this litttle bit confusing. I have two problems actualy.
First - main problem is that library is not returning expected value.
I think that 04.02.2019 at 01:55 shouldn't be blue shift but Red shift.
You can see it also from this picture (R - is day shift and N is Night).
So If night shift starts 3.2. at 18:00 it should end at 6:00. So it should be red shift.
This is my main problem (It can be also my mistake but I checked your examples and I think my settings of rotation should be OK).
This problem leads me to deubgging so I wanted to understand whats going wrong.
I wanted to try PrintShiftInstances. Here is little snippet
Středa = Wednesday
Čtvrtek = Thursday
Leden = January
Únor = February
I will debug this in Visual Studio. The quick check in java that I ran gave the same answer as in C#, but both could be wrong.
First, there is a bug in WorkSchedule.cs on line 434. The comparison of dates should be:
if (start.CompareTo(end) > 0)
I will submit this fix to Git and I appreciate you pointing out this issue to me.
Second, I cannot find an issue with your work schedule. Perhaps it is a matter of interpretation of how I have defined a Rotation and RotationSegment. Shifts that cross midnight are always difficult.
Here is the test code that can be added to the TestPartial() method and executed in Visual Studio:
[TestClass]
public class TestSnippet : BaseTest
{
[TestMethod]
public void TestPartial()
{
WorkSchedule _workSchedule = new WorkSchedule("scheduleName", "description");
// Day shift, starts at 06:00 for 12 hours
Shift day = _workSchedule.CreateShift("Day", "Day shift", new LocalTime(6, 0, 0), Duration.FromHours(12));
// Night shift, starts at 18:00 for 12 hours
Shift night = _workSchedule.CreateShift("Night", "Night shift", new LocalTime(18, 0, 0), Duration.FromHours(12));
// rotation
Rotation rotation = _workSchedule.CreateRotation("My rotation", "description..");
rotation.AddSegment(day, 2, 2);
rotation.AddSegment(night, 3, 2);
rotation.AddSegment(day, 2, 3);
rotation.AddSegment(night, 2, 2);
rotation.AddSegment(day, 3, 2);
rotation.AddSegment(night, 2, 3);
// reference date for start of shift rotations
LocalDate aDate = new LocalDate(2019, 1, 7);
LocalDate referenceDate = aDate.PlusDays(-28);
_workSchedule.CreateTeam("Blue", "First team", rotation, referenceDate);
_workSchedule.CreateTeam("Yellow", "Second team", rotation, referenceDate.PlusDays(14));
_workSchedule.CreateTeam("Red", "Third team", rotation, referenceDate.PlusDays(21));
_workSchedule.CreateTeam("Green", "Fourth team", rotation, referenceDate.PlusDays(7));
_workSchedule.PrintShiftInstances(aDate.PlusDays(-1), aDate.PlusDays(29));
}
}
I attempted to reproduce the diagram with the 1.1 ... columns on Monday where your red mark is drawn.
Your rotation is 28 days long. The test defines a rotation start for Blue shift of -28 days from 2019/1/7 (2018/12/10), 7 days later for Green, 14 days later for Yellow and 21 days later for Red shift. The ShiftInstances are then printed out starting on the day before Monday 2019/1/7 (i.e. Sunday the 8th) through an entire rotation of 28 days. Here is the output:
[1] : Sunday, January 06, 2019
(1) Team: Green, Shift: Day, Start: 1/6/2019 6:00:00 AM, End: 1/6/2019 6:00:00 PM
(2) Team: Red, Shift: Night, Start: 1/6/2019 6:00:00 PM, End: 1/7/2019 6:00:00 AM
[2] : Monday, January 07, 2019
(1) Team: Blue, Shift: Day, Start: 1/7/2019 6:00:00 AM, End: 1/7/2019 6:00:00 PM
(2) Team: Yellow, Shift: Night, Start: 1/7/2019 6:00:00 PM, End: 1/8/2019 6:00:00 AM
[3] : Tuesday, January 08, 2019
(1) Team: Blue, Shift: Day, Start: 1/8/2019 6:00:00 AM, End: 1/8/2019 6:00:00 PM
(2) Team: Yellow, Shift: Night, Start: 1/8/2019 6:00:00 PM, End: 1/9/2019 6:00:00 AM
[4] : Wednesday, January 09, 2019
(1) Team: Red, Shift: Day, Start: 1/9/2019 6:00:00 AM, End: 1/9/2019 6:00:00 PM
(2) Team: Green, Shift: Night, Start: 1/9/2019 6:00:00 PM, End: 1/10/2019 6:00:00 AM
[5] : Thursday, January 10, 2019
(1) Team: Red, Shift: Day, Start: 1/10/2019 6:00:00 AM, End: 1/10/2019 6:00:00 PM
(2) Team: Green, Shift: Night, Start: 1/10/2019 6:00:00 PM, End: 1/11/2019 6:00:00 AM
[6] : Friday, January 11, 2019
(1) Team: Yellow, Shift: Day, Start: 1/11/2019 6:00:00 AM, End: 1/11/2019 6:00:00 PM
(2) Team: Blue, Shift: Night, Start: 1/11/2019 6:00:00 PM, End: 1/12/2019 6:00:00 AM
[7] : Saturday, January 12, 2019
(1) Team: Yellow, Shift: Day, Start: 1/12/2019 6:00:00 AM, End: 1/12/2019 6:00:00 PM
(2) Team: Blue, Shift: Night, Start: 1/12/2019 6:00:00 PM, End: 1/13/2019 6:00:00 AM
[8] : Sunday, January 13, 2019
(1) Team: Yellow, Shift: Day, Start: 1/13/2019 6:00:00 AM, End: 1/13/2019 6:00:00 PM
(2) Team: Blue, Shift: Night, Start: 1/13/2019 6:00:00 PM, End: 1/14/2019 6:00:00 AM
[9] : Monday, January 14, 2019
(1) Team: Green, Shift: Day, Start: 1/14/2019 6:00:00 AM, End: 1/14/2019 6:00:00 PM
(2) Team: Red, Shift: Night, Start: 1/14/2019 6:00:00 PM, End: 1/15/2019 6:00:00 AM
[10] : Tuesday, January 15, 2019
(1) Team: Green, Shift: Day, Start: 1/15/2019 6:00:00 AM, End: 1/15/2019 6:00:00 PM
(2) Team: Red, Shift: Night, Start: 1/15/2019 6:00:00 PM, End: 1/16/2019 6:00:00 AM
[11] : Wednesday, January 16, 2019
(1) Team: Blue, Shift: Day, Start: 1/16/2019 6:00:00 AM, End: 1/16/2019 6:00:00 PM
(2) Team: Yellow, Shift: Night, Start: 1/16/2019 6:00:00 PM, End: 1/17/2019 6:00:00 AM
[12] : Thursday, January 17, 2019
(1) Team: Blue, Shift: Day, Start: 1/17/2019 6:00:00 AM, End: 1/17/2019 6:00:00 PM
(2) Team: Yellow, Shift: Night, Start: 1/17/2019 6:00:00 PM, End: 1/18/2019 6:00:00 AM
[13] : Friday, January 18, 2019
(1) Team: Red, Shift: Day, Start: 1/18/2019 6:00:00 AM, End: 1/18/2019 6:00:00 PM
(2) Team: Green, Shift: Night, Start: 1/18/2019 6:00:00 PM, End: 1/19/2019 6:00:00 AM
[14] : Saturday, January 19, 2019
(1) Team: Red, Shift: Day, Start: 1/19/2019 6:00:00 AM, End: 1/19/2019 6:00:00 PM
(2) Team: Green, Shift: Night, Start: 1/19/2019 6:00:00 PM, End: 1/20/2019 6:00:00 AM
[15] : Sunday, January 20, 2019
(1) Team: Red, Shift: Day, Start: 1/20/2019 6:00:00 AM, End: 1/20/2019 6:00:00 PM
(2) Team: Green, Shift: Night, Start: 1/20/2019 6:00:00 PM, End: 1/21/2019 6:00:00 AM
[16] : Monday, January 21, 2019
(1) Team: Yellow, Shift: Day, Start: 1/21/2019 6:00:00 AM, End: 1/21/2019 6:00:00 PM
(2) Team: Blue, Shift: Night, Start: 1/21/2019 6:00:00 PM, End: 1/22/2019 6:00:00 AM
[17] : Tuesday, January 22, 2019
(1) Team: Yellow, Shift: Day, Start: 1/22/2019 6:00:00 AM, End: 1/22/2019 6:00:00 PM
(2) Team: Blue, Shift: Night, Start: 1/22/2019 6:00:00 PM, End: 1/23/2019 6:00:00 AM
[18] : Wednesday, January 23, 2019
(1) Team: Green, Shift: Day, Start: 1/23/2019 6:00:00 AM, End: 1/23/2019 6:00:00 PM
(2) Team: Red, Shift: Night, Start: 1/23/2019 6:00:00 PM, End: 1/24/2019 6:00:00 AM
[19] : Thursday, January 24, 2019
(1) Team: Green, Shift: Day, Start: 1/24/2019 6:00:00 AM, End: 1/24/2019 6:00:00 PM
(2) Team: Red, Shift: Night, Start: 1/24/2019 6:00:00 PM, End: 1/25/2019 6:00:00 AM
[20] : Friday, January 25, 2019
(1) Team: Blue, Shift: Day, Start: 1/25/2019 6:00:00 AM, End: 1/25/2019 6:00:00 PM
(2) Team: Yellow, Shift: Night, Start: 1/25/2019 6:00:00 PM, End: 1/26/2019 6:00:00 AM
[21] : Saturday, January 26, 2019
(1) Team: Blue, Shift: Day, Start: 1/26/2019 6:00:00 AM, End: 1/26/2019 6:00:00 PM
(2) Team: Yellow, Shift: Night, Start: 1/26/2019 6:00:00 PM, End: 1/27/2019 6:00:00 AM
[22] : Sunday, January 27, 2019
(1) Team: Blue, Shift: Day, Start: 1/27/2019 6:00:00 AM, End: 1/27/2019 6:00:00 PM
(2) Team: Yellow, Shift: Night, Start: 1/27/2019 6:00:00 PM, End: 1/28/2019 6:00:00 AM
[23] : Monday, January 28, 2019
(1) Team: Red, Shift: Day, Start: 1/28/2019 6:00:00 AM, End: 1/28/2019 6:00:00 PM
(2) Team: Green, Shift: Night, Start: 1/28/2019 6:00:00 PM, End: 1/29/2019 6:00:00 AM
[24] : Tuesday, January 29, 2019
(1) Team: Red, Shift: Day, Start: 1/29/2019 6:00:00 AM, End: 1/29/2019 6:00:00 PM
(2) Team: Green, Shift: Night, Start: 1/29/2019 6:00:00 PM, End: 1/30/2019 6:00:00 AM
[25] : Wednesday, January 30, 2019
(1) Team: Yellow, Shift: Day, Start: 1/30/2019 6:00:00 AM, End: 1/30/2019 6:00:00 PM
(2) Team: Blue, Shift: Night, Start: 1/30/2019 6:00:00 PM, End: 1/31/2019 6:00:00 AM
[26] : Thursday, January 31, 2019
(1) Team: Yellow, Shift: Day, Start: 1/31/2019 6:00:00 AM, End: 1/31/2019 6:00:00 PM
(2) Team: Blue, Shift: Night, Start: 1/31/2019 6:00:00 PM, End: 2/1/2019 6:00:00 AM
[27] : Friday, February 01, 2019
(1) Team: Green, Shift: Day, Start: 2/1/2019 6:00:00 AM, End: 2/1/2019 6:00:00 PM
(2) Team: Red, Shift: Night, Start: 2/1/2019 6:00:00 PM, End: 2/2/2019 6:00:00 AM
[28] : Saturday, February 02, 2019
(1) Team: Green, Shift: Day, Start: 2/2/2019 6:00:00 AM, End: 2/2/2019 6:00:00 PM
(2) Team: Red, Shift: Night, Start: 2/2/2019 6:00:00 PM, End: 2/3/2019 6:00:00 AM
[29] : Sunday, February 03, 2019
(1) Team: Green, Shift: Day, Start: 2/3/2019 6:00:00 AM, End: 2/3/2019 6:00:00 PM
(2) Team: Red, Shift: Night, Start: 2/3/2019 6:00:00 PM, End: 2/4/2019 6:00:00 AM
[30] : Monday, February 04, 2019
(1) Team: Blue, Shift: Day, Start: 2/4/2019 6:00:00 AM, End: 2/4/2019 6:00:00 PM
(2) Team: Yellow, Shift: Night, Start: 2/4/2019 6:00:00 PM, End: 2/5/2019 6:00:00 AM
[31] : Tuesday, February 05, 2019
(1) Team: Blue, Shift: Day, Start: 2/5/2019 6:00:00 AM, End: 2/5/2019 6:00:00 PM
(2) Team: Yellow, Shift: Night, Start: 2/5/2019 6:00:00 PM, End: 2/6/2019 6:00:00 AM
On Monday morning, the Red night shift ends at 06:00. The Blue day shift then starts at 06:00. So at 01:55 on Monday, the Red shift is still working.
Thank you!
I can confirm that PrintShiftInstances()
now working correctly.
I totally agree, cross midnight shifts are very difficult. I think my problem will be much deeper in implementation.
My task is that I have DateTime and I need to get shift which was at work.
So I used method GetShiftInstancesForTime, but there is no verification for cross midnight shift.
That means proper one team is filtered out and only teams for day 4.2. are returned.
Quetion is where we should perform verification for cross midnight shift.
I saw some your samples whre you had 3 shifts per day - there has to be same problem with cross-midnight shifts, right?
Yes, there is a bug when a shift crosses midnight. The GetShiftInstancesForTime() method picks up tomorrow's shift instance. I have made fixes in two files, ShiftInstance.cs and WorkSchedule.cs.. These files are attached in the zip file.
Here is test code for the changes:
LocalDateTime ldt = new LocalDateTime(2019, 1, 7, 3, 0, 0);
List<ShiftInstance> instances = _workSchedule.GetShiftInstancesForTime(ldt);
foreach (ShiftInstance instance in instances) {
Console.WriteLine("At " + ldt.ToString() + ": " + instance.ToString());
}
ldt = new LocalDateTime(2019, 1, 7, 12, 0, 0);
instances = _workSchedule.GetShiftInstancesForTime(ldt);
foreach (ShiftInstance instance in instances)
{
Console.WriteLine("At " + ldt.ToString() + ": " + instance.ToString());
}
ldt = new LocalDateTime(2019, 1, 7, 21, 0, 0);
instances = _workSchedule.GetShiftInstancesForTime(ldt);
foreach (ShiftInstance instance in instances)
{
Console.WriteLine("At " + ldt.ToString() + ": " + instance.ToString());
}
The console output is:
At 1/7/2019 3:00:00 AM: Team: Red, Shift: Night, Start: 1/6/2019 6:00:00 PM, End: 1/7/2019 6:00:00 AM
At 1/7/2019 12:00:00 PM: Team: Blue, Shift: Day, Start: 1/7/2019 6:00:00 AM, End: 1/7/2019 6:00:00 PM
At 1/7/2019 9:00:00 PM: Team: Yellow, Shift: Night, Start: 1/7/2019 6:00:00 PM, End: 1/8/2019 6:00:00 AM
Please verify that these are the expected shifts for that date.
I also added the GetAllShiftInstancesForDay() method in WorkSchedule.cs that returns all of the shift instances with working time in a given day. The GetShiftInstancesForDay() method returns the ones that start in a given day.
Issues have been fixed in v1.1.1.
Awesome !
Than you very much, works like a charm.
I owe you!