public void TestTwoTeam() { string description = "This is a fixed (no rotation) plan that uses 2 teams and two 12-hr shifts to provide 24/7 coverage. " + "One team will be permanently on the day shift and the other will be on the night shift."; schedule = new WorkSchedule("2 Team Fixed 12 Plan", description); // Day shift, starts at 07:00 for 12 hours Shift day = schedule.CreateShift("Day", "Day shift", new LocalTime(7, 0, 0), Duration.FromHours(12)); // Night shift, starts at 19:00 for 12 hours Shift night = schedule.CreateShift("Night", "Night shift", new LocalTime(19, 0, 0), Duration.FromHours(12)); // Team1 rotation Rotation team1Rotation = schedule.CreateRotation("Team1", "Team1"); team1Rotation.AddSegment(day, 1, 0); // Team1 rotation Rotation team2Rotation = schedule.CreateRotation("Team2", "Team2"); team2Rotation.AddSegment(night, 1, 0); schedule.CreateTeam("Team 1", "First team", team1Rotation, referenceDate); schedule.CreateTeam("Team 2", "Second team", team2Rotation, referenceDate); RunBaseTest(schedule, Duration.FromHours(12), Duration.FromDays(1), referenceDate); }
public void TestManufacturingShifts() { // manufacturing company schedule = new WorkSchedule("Manufacturing Company - four twelves", "Four 12 hour alternating day/night shifts"); // day shift, start at 07:00 for 12 hours Shift day = schedule.CreateShift("Day", "Day shift", new LocalTime(7, 0, 0), Duration.FromHours(12)); // night shift, start at 19:00 for 12 hours Shift night = schedule.CreateShift("Night", "Night shift", new LocalTime(19, 0, 0), Duration.FromHours(12)); // 7 days ON, 7 OFF Rotation dayRotation = schedule.CreateRotation("Day", "Day"); dayRotation.AddSegment(day, 7, 7); // 7 nights ON, 7 OFF Rotation nightRotation = schedule.CreateRotation("Night", "Night"); nightRotation.AddSegment(night, 7, 7); schedule.CreateTeam("A", "A day shift", dayRotation, new LocalDate(2014, 1, 2)); schedule.CreateTeam("B", "B night shift", nightRotation, new LocalDate(2014, 1, 2)); schedule.CreateTeam("C", "C day shift", dayRotation, new LocalDate(2014, 1, 9)); schedule.CreateTeam("D", "D night shift", nightRotation, new LocalDate(2014, 1, 9)); RunBaseTest(schedule, Duration.FromHours(84), Duration.FromDays(14), new LocalDate(2014, 1, 9)); }
public void TestFirefighterShifts1() { // Kern Co, CA schedule = new WorkSchedule("Kern Co.", "Three 24 hour alternating shifts"); // shift, start 07:00 for 24 hours Shift shift = schedule.CreateShift("24 Hour", "24 hour shift", new LocalTime(7, 0, 0), Duration.FromHours(24)); // 2 days ON, 2 OFF, 2 ON, 2 OFF, 2 ON, 8 OFF Rotation rotation = schedule.CreateRotation("24 Hour", "2 days ON, 2 OFF, 2 ON, 2 OFF, 2 ON, 8 OFF"); rotation.AddSegment(shift, 2, 2); rotation.AddSegment(shift, 2, 2); rotation.AddSegment(shift, 2, 8); Team platoon1 = schedule.CreateTeam("Red", "A Shift", rotation, new LocalDate(2017, 1, 8)); Team platoon2 = schedule.CreateTeam("Black", "B Shift", rotation, new LocalDate(2017, 2, 1)); Team platoon3 = schedule.CreateTeam("Green", "C Shift", rotation, new LocalDate(2017, 1, 2)); List <ShiftInstance> instances = schedule.GetShiftInstancesForDay(new LocalDate(2017, 3, 1)); Assert.IsTrue(instances.Count == 1); Assert.IsTrue(instances[0].Team.Equals(platoon3)); instances = schedule.GetShiftInstancesForDay(new LocalDate(2017, 3, 3)); Assert.IsTrue(instances.Count == 1); Assert.IsTrue(instances[0].Team.Equals(platoon1)); instances = schedule.GetShiftInstancesForDay(new LocalDate(2017, 3, 9)); Assert.IsTrue(instances.Count == 1); Assert.IsTrue(instances[0].Team.Equals(platoon2)); RunBaseTest(schedule, Duration.FromHours(144), Duration.FromDays(18), new LocalDate(2017, 2, 1)); }
public void TestDupont() { string description = "The DuPont 12-hour rotating shift schedule uses 4 teams (crews) and 2 twelve-hour shifts to provide 24/7 coverage. " + "It consists of a 4-week cycle where each team works 4 consecutive night shifts, " + "followed by 3 days off duty, works 3 consecutive day shifts, followed by 1 day off duty, works 3 consecutive night shifts, " + "followed by 3 days off duty, work 4 consecutive day shift, then have 7 consecutive days off duty. " + "Personnel works an average 42 hours per week."; schedule = new WorkSchedule("DuPont Shift Schedule", description); // Day shift, starts at 07:00 for 12 hours Shift day = schedule.CreateShift("Day", "Day shift", new LocalTime(7, 0, 0), Duration.FromHours(12)); // Night shift, starts at 19:00 for 12 hours Shift night = schedule.CreateShift("Night", "Night shift", new LocalTime(19, 0, 0), Duration.FromHours(12)); // Team1 rotation Rotation rotation = schedule.CreateRotation("DuPont", "DuPont"); rotation.AddSegment(night, 4, 3); rotation.AddSegment(day, 3, 1); rotation.AddSegment(night, 3, 3); rotation.AddSegment(day, 4, 7); schedule.CreateTeam("Team 1", "First team", rotation, referenceDate); schedule.CreateTeam("Team 2", "Second team", rotation, referenceDate.PlusDays(-7)); schedule.CreateTeam("Team 3", "Third team", rotation, referenceDate.PlusDays(-14)); schedule.CreateTeam("Team 4", "Forth team", rotation, referenceDate.PlusDays(-21)); RunBaseTest(schedule, Duration.FromHours(168), Duration.FromDays(28), referenceDate); }
public void TestPostalServiceShifts() { // United States Postal Service schedule = new WorkSchedule("USPS", "Six 9 hr shifts, rotating every 42 days"); // shift, start at 08:00 for 9 hours Shift day = schedule.CreateShift("Day", "day shift", new LocalTime(8, 0, 0), Duration.FromHours(9)); Rotation rotation = schedule.CreateRotation("Day", "Day"); rotation.AddSegment(day, 3, 7); rotation.AddSegment(day, 1, 7); rotation.AddSegment(day, 1, 7); rotation.AddSegment(day, 1, 7); rotation.AddSegment(day, 1, 7); LocalDate rotationStart = new LocalDate(2017, 1, 27); // day teams schedule.CreateTeam("Team A", "A team", rotation, rotationStart); schedule.CreateTeam("Team B", "B team", rotation, rotationStart.Minus(Period.FromDays(7))); schedule.CreateTeam("Team C", "C team", rotation, rotationStart.Minus(Period.FromDays(14))); schedule.CreateTeam("Team D", "D team", rotation, rotationStart.Minus(Period.FromDays(21))); schedule.CreateTeam("Team E", "E team", rotation, rotationStart.Minus(Period.FromDays(28))); schedule.CreateTeam("Team F", "F team", rotation, rotationStart.Minus(Period.FromDays(35))); RunBaseTest(schedule, Duration.FromHours(63), Duration.FromDays(42), rotationStart); }
public void TestDNO() { string description = "This is a fast rotation plan that uses 3 teams and two 12-hr shifts to provide 24/7 coverage. " + "Each team rotates through the following sequence every three days: 1 day shift, 1 night shift, and 1 day off."; schedule = new WorkSchedule("DNO Plan", description); // Day shift, starts at 07:00 for 12 hours Shift day = schedule.CreateShift("Day", "Day shift", new LocalTime(7, 0, 0), Duration.FromHours(12)); // Night shift, starts at 19:00 for 12 hours Shift night = schedule.CreateShift("Night", "Night shift", new LocalTime(19, 0, 0), Duration.FromHours(12)); // rotation Rotation rotation = schedule.CreateRotation("DNO", "DNO"); rotation.AddSegment(day, 1, 0); rotation.AddSegment(night, 1, 1); schedule.CreateTeam("Team 1", "First team", rotation, referenceDate); schedule.CreateTeam("Team 2", "Second team", rotation, referenceDate.PlusDays(-1)); schedule.CreateTeam("Team 3", "Third team", rotation, referenceDate.PlusDays(-2)); // rotation working time LocalDateTime from = referenceDate.PlusDays(rotation.GetDayCount()).At(new LocalTime(7, 0, 0)); Duration duration = schedule.CalculateWorkingTime(from, from.PlusDays(3)); Assert.IsTrue(duration.Equals(Duration.FromHours(72))); RunBaseTest(schedule, Duration.FromHours(24), Duration.FromDays(3), referenceDate); }
public void TestLowNight() { string description = "Low night demand"; schedule = new WorkSchedule("Low Night Demand Plan", description); // 3 shifts Shift day = schedule.CreateShift("Day", "Day shift", new LocalTime(7, 0, 0), Duration.FromHours(8)); Shift swing = schedule.CreateShift("Swing", "Swing shift", new LocalTime(15, 0, 0), Duration.FromHours(8)); Shift night = schedule.CreateShift("Night", "Night shift", new LocalTime(23, 0, 0), Duration.FromHours(8)); // Team rotation Rotation rotation = schedule.CreateRotation("Low night demand", "Low night demand"); rotation.AddSegment(day, 3, 0); rotation.AddSegment(swing, 4, 3); rotation.AddSegment(day, 4, 0); rotation.AddSegment(swing, 3, 4); rotation.AddSegment(day, 3, 0); rotation.AddSegment(night, 4, 3); rotation.AddSegment(day, 4, 0); rotation.AddSegment(night, 3, 4); // 6 teams schedule.CreateTeam("Team1", "First team", rotation, referenceDate); schedule.CreateTeam("Team2", "Second team", rotation, referenceDate.PlusDays(-21)); schedule.CreateTeam("Team3", "Third team", rotation, referenceDate.PlusDays(-7)); schedule.CreateTeam("Team4", "Fourth team", rotation, referenceDate.PlusDays(-28)); schedule.CreateTeam("Team5", "Fifth team", rotation, referenceDate.PlusDays(-14)); schedule.CreateTeam("Team6", "Sixth team", rotation, referenceDate.PlusDays(-35)); RunBaseTest(schedule, Duration.FromHours(224), Duration.FromDays(42), referenceDate); }
public void TestICUInterns() { string description = "This plan supports a combination of 14-hr day shift , 15.5-hr cross-cover shift , and a 14-hr night shift for medical interns. " + "The day shift and the cross-cover shift have the same start time (7:00AM). " + "The night shift starts at around 10:00PM and ends at 12:00PM on the next day."; schedule = new WorkSchedule("ICU Interns Plan", description); // Day shift #1, starts at 07:00 for 15.5 hours Shift crossover = schedule.CreateShift("Crossover", "Day shift #1 cross-over", new LocalTime(7, 0, 0), Duration.FromHours(15).Plus(Duration.FromMinutes(30))); // Day shift #2, starts at 07:00 for 14 hours Shift day = schedule.CreateShift("Day", "Day shift #2", new LocalTime(7, 0, 0), Duration.FromHours(14)); // Night shift, starts at 22:00 for 14 hours Shift night = schedule.CreateShift("Night", "Night shift", new LocalTime(22, 0, 0), Duration.FromHours(14)); // Team1 rotation Rotation rotation = schedule.CreateRotation("ICU", "ICU"); rotation.AddSegment(day, 1, 0); rotation.AddSegment(crossover, 1, 0); rotation.AddSegment(night, 1, 1); schedule.CreateTeam("Team 1", "First team", rotation, referenceDate); schedule.CreateTeam("Team 2", "Second team", rotation, referenceDate.PlusDays(-3)); schedule.CreateTeam("Team 3", "Third team", rotation, referenceDate.PlusDays(-2)); schedule.CreateTeam("Team 4", "Forth team", rotation, referenceDate.PlusDays(-1)); RunBaseTest(schedule, Duration.FromMinutes(2610), Duration.FromDays(4), referenceDate); }
public void Test549() { string description = "Compressed work schedule."; schedule = new WorkSchedule("5/4/9 Plan", description); // Shift 1 starts at 07:00 for 9 hours Shift day1 = schedule.CreateShift("Day1", "Day shift #1", new LocalTime(7, 0, 0), Duration.FromHours(9)); // Shift 2 starts at 07:00 for 8 hours Shift day2 = schedule.CreateShift("Day2", "Day shift #2", new LocalTime(7, 0, 0), Duration.FromHours(8)); // Team rotation (28 days) Rotation rotation = schedule.CreateRotation("5/4/9 ", "5/4/9 "); rotation.AddSegment(day1, 4, 0); rotation.AddSegment(day2, 1, 3); rotation.AddSegment(day1, 4, 3); rotation.AddSegment(day1, 4, 2); rotation.AddSegment(day1, 4, 0); rotation.AddSegment(day2, 1, 2); // 2 teams schedule.CreateTeam("Team1", "First team", rotation, referenceDate); schedule.CreateTeam("Team2", "Second team", rotation, referenceDate.PlusDays(-14)); RunBaseTest(schedule, Duration.FromHours(160), Duration.FromDays(28), referenceDate); }
public void TestNursingICUShifts() { // ER nursing schedule schedule = new WorkSchedule("Nursing ICU", "Two 12 hr back-to-back shifts, rotating every 14 days"); // day shift, starts at 06:00 for 12 hours Shift day = schedule.CreateShift("Day", "Day shift", new LocalTime(6, 0, 0), Duration.FromHours(12)); // night shift, starts at 18:00 for 12 hours Shift night = schedule.CreateShift("Night", "Night shift", new LocalTime(18, 0, 0), Duration.FromHours(12)); // day rotation Rotation dayRotation = schedule.CreateRotation("Day", "Day"); dayRotation.AddSegment(day, 3, 4); dayRotation.AddSegment(day, 4, 3); // inverse day rotation (day + 3 days) Rotation inverseDayRotation = schedule.CreateRotation("Inverse Day", "Inverse Day"); inverseDayRotation.AddSegment(day, 0, 3); inverseDayRotation.AddSegment(day, 4, 4); inverseDayRotation.AddSegment(day, 3, 0); // night rotation Rotation nightRotation = schedule.CreateRotation("Night", "Night"); nightRotation.AddSegment(night, 4, 3); nightRotation.AddSegment(night, 3, 4); // inverse night rotation Rotation inverseNightRotation = schedule.CreateRotation("Inverse Night", "Inverse Night"); inverseNightRotation.AddSegment(night, 0, 4); inverseNightRotation.AddSegment(night, 3, 3); inverseNightRotation.AddSegment(night, 4, 0); LocalDate rotationStart = new LocalDate(2014, 1, 6); schedule.CreateTeam("A", "Day shift", dayRotation, rotationStart); schedule.CreateTeam("B", "Day inverse shift", inverseDayRotation, rotationStart); schedule.CreateTeam("C", "Night shift", nightRotation, rotationStart); schedule.CreateTeam("D", "Night inverse shift", inverseNightRotation, rotationStart); RunBaseTest(schedule, Duration.FromHours(84), Duration.FromDays(14), rotationStart); }
public void TestPanama() { string description = "This is a slow rotation plan that uses 4 teams and two 12-hr shifts to provide 24/7 coverage. " + "The working and non-working days follow this pattern: 2 days on, 2 days off, 3 days on, 2 days off, 2 days on, 3 days off. " + "Each team works the same shift (day or night) for 28 days then switches over to the other shift for the next 28 days. " + "After 56 days, the same sequence starts over."; string scheduleName = "Panama"; schedule = new WorkSchedule(scheduleName, description); // Day shift, starts at 07:00 for 12 hours Shift day = schedule.CreateShift("Day", "Day shift", new LocalTime(7, 0, 0), Duration.FromHours(12)); // Night shift, starts at 19:00 for 12 hours Shift night = schedule.CreateShift("Night", "Night shift", new LocalTime(19, 0, 0), Duration.FromHours(12)); // rotation Rotation rotation = schedule.CreateRotation("Panama", "2 days on, 2 days off, 3 days on, 2 days off, 2 days on, 3 days off"); // 2 days on, 2 off, 3 on, 2 off, 2 on, 3 off (and repeat) rotation.AddSegment(day, 2, 2); rotation.AddSegment(day, 3, 2); rotation.AddSegment(day, 2, 3); rotation.AddSegment(day, 2, 2); rotation.AddSegment(day, 3, 2); rotation.AddSegment(day, 2, 3); // 2 nights on, 2 off, 3 on, 2 off, 2 on, 3 off (and repeat) rotation.AddSegment(night, 2, 2); rotation.AddSegment(night, 3, 2); rotation.AddSegment(night, 2, 3); rotation.AddSegment(night, 2, 2); rotation.AddSegment(night, 3, 2); rotation.AddSegment(night, 2, 3); // reference date for start of shift rotations LocalDate referenceDate = new LocalDate(2016, 10, 31); schedule.CreateTeam("Team 1", "First team", rotation, referenceDate); schedule.CreateTeam("Team 2", "Second team", rotation, referenceDate.PlusDays(-28)); schedule.CreateTeam("Team 3", "Third team", rotation, referenceDate.PlusDays(-7)); schedule.CreateTeam("Team 4", "Fourth team", rotation, referenceDate.PlusDays(-35)); RunBaseTest(schedule, Duration.FromHours(336), Duration.FromDays(56), referenceDate); }
public void Test9to5() { string description = "This is the basic 9 to 5 schedule plan for office employees. Every employee works 8 hrs a day from Monday to Friday."; schedule = new WorkSchedule("9 To 5 Plan", description); // Shift starts at 09:00 for 8 hours Shift day = schedule.CreateShift("Day", "Day shift", new LocalTime(9, 0, 0), Duration.FromHours(8)); // Team1 rotation (5 days) Rotation rotation = schedule.CreateRotation("9 To 5 ", "9 To 5 "); rotation.AddSegment(day, 5, 2); // 1 team, 1 shift schedule.CreateTeam("Team", "One team", rotation, referenceDate); RunBaseTest(schedule, Duration.FromHours(40), Duration.FromDays(7), referenceDate); }
public void Test8Plus12() { string description = "This is a fast rotation plan that uses 4 teams and a combination of three 8-hr shifts on weekdays " + "and two 12-hr shifts on weekends to provide 24/7 coverage."; // work schedule schedule = new WorkSchedule("8 Plus 12 Plan", description); // Day shift #1, starts at 07:00 for 12 hours Shift day1 = schedule.CreateShift("Day1", "Day shift #1", new LocalTime(7, 0, 0), Duration.FromHours(12)); // Day shift #2, starts at 07:00 for 8 hours Shift day2 = schedule.CreateShift("Day2", "Day shift #2", new LocalTime(7, 0, 0), Duration.FromHours(8)); // Swing shift, starts at 15:00 for 8 hours Shift swing = schedule.CreateShift("Swing", "Swing shift", new LocalTime(15, 0, 0), Duration.FromHours(8)); // Night shift #1, starts at 19:00 for 12 hours Shift night1 = schedule.CreateShift("Night1", "Night shift #1", new LocalTime(19, 0, 0), Duration.FromHours(12)); // Night shift #2, starts at 23:00 for 8 hours Shift night2 = schedule.CreateShift("Night2", "Night shift #2", new LocalTime(23, 0, 0), Duration.FromHours(8)); // shift rotation (28 days) Rotation rotation = schedule.CreateRotation("8 Plus 12", "8 Plus 12"); rotation.AddSegment(day2, 5, 0); rotation.AddSegment(day1, 2, 3); rotation.AddSegment(night2, 2, 0); rotation.AddSegment(night1, 2, 0); rotation.AddSegment(night2, 3, 4); rotation.AddSegment(swing, 5, 2); // 4 teams, rotating through 5 shifts schedule.CreateTeam("Team 1", "First team", rotation, referenceDate); schedule.CreateTeam("Team 2", "Second team", rotation, referenceDate.PlusDays(-7)); schedule.CreateTeam("Team 3", "Third team", rotation, referenceDate.PlusDays(-14)); schedule.CreateTeam("Team 4", "Fourth team", rotation, referenceDate.PlusDays(-21)); RunBaseTest(schedule, Duration.FromHours(168), Duration.FromDays(28), referenceDate); }
public void TestFirefighterShifts2() { // Seattle, WA fire shifts schedule = new WorkSchedule("Seattle", "Four 24 hour alternating shifts"); // shift, start at 07:00 for 24 hours Shift shift = schedule.CreateShift("24 Hours", "24 hour shift", new LocalTime(7, 0, 0), Duration.FromHours(24)); // 1 day ON, 4 OFF, 1 ON, 2 OFF Rotation rotation = schedule.CreateRotation("24 Hours", "24 Hours"); rotation.AddSegment(shift, 1, 4); rotation.AddSegment(shift, 1, 2); schedule.CreateTeam("A", "Platoon1", rotation, new LocalDate(2014, 2, 2)); schedule.CreateTeam("B", "Platoon2", rotation, new LocalDate(2014, 2, 4)); schedule.CreateTeam("C", "Platoon3", rotation, new LocalDate(2014, 1, 31)); schedule.CreateTeam("D", "Platoon4", rotation, new LocalDate(2014, 1, 29)); RunBaseTest(schedule, Duration.FromHours(48), Duration.FromDays(8), new LocalDate(2014, 2, 4)); }
public void Test3TeamFixed24() { string description = "Fire departments"; schedule = new WorkSchedule("3 Team Fixed 24 Plan", description); // Shift starts at 00:00 for 24 hours Shift shift = schedule.CreateShift("24 Hour", "24 hour shift", new LocalTime(0, 0, 0), Duration.FromHours(24)); // Team rotation Rotation rotation = schedule.CreateRotation("3 Team Fixed 24 Plan", "3 Team Fixed 24 Plan"); rotation.AddSegment(shift, 1, 1); rotation.AddSegment(shift, 1, 1); rotation.AddSegment(shift, 1, 4); // 3 teams schedule.CreateTeam("Team1", "First team", rotation, referenceDate); schedule.CreateTeam("Team2", "Second team", rotation, referenceDate.PlusDays(-3)); schedule.CreateTeam("Team3", "Third team", rotation, referenceDate.PlusDays(-6)); RunBaseTest(schedule, Duration.FromHours(72), Duration.FromDays(9), referenceDate); }
public void TestGenericShift() { // regular work week with holidays and breaks schedule = new WorkSchedule("Regular 40 hour work week", "9 to 5"); // holidays NonWorkingPeriod memorialDay = schedule.CreateNonWorkingPeriod("MEMORIAL DAY", "Memorial day", new LocalDateTime(2016, 5, 30, 0, 0, 0), Duration.FromHours(24)); schedule.CreateNonWorkingPeriod("INDEPENDENCE DAY", "Independence day", new LocalDateTime(2016, 7, 4, 0, 0, 0), Duration.FromHours(24)); schedule.CreateNonWorkingPeriod("LABOR DAY", "Labor day", new LocalDateTime(2016, 9, 5, 0, 0, 0), Duration.FromHours(24)); schedule.CreateNonWorkingPeriod("THANKSGIVING", "Thanksgiving day and day after", new LocalDateTime(2016, 11, 24, 0, 0, 0), Duration.FromHours(48)); schedule.CreateNonWorkingPeriod("CHRISTMAS SHUTDOWN", "Christmas week scheduled maintenance", new LocalDateTime(2016, 12, 25, 0, 30, 0), Duration.FromHours(168)); // each shift duration Duration shiftDuration = Duration.FromHours(8); LocalTime shift1Start = new LocalTime(7, 0, 0); LocalTime shift2Start = new LocalTime(15, 0, 0); // shift 1 Shift shift1 = schedule.CreateShift("Shift1", "Shift #1", shift1Start, shiftDuration); // breaks shift1.CreateBreak("10AM", "10 am break", new LocalTime(10, 0, 0), Duration.FromMinutes(15)); shift1.CreateBreak("LUNCH", "lunch", new LocalTime(12, 0, 0), Duration.FromHours(1)); shift1.CreateBreak("2PM", "2 pm break", new LocalTime(14, 0, 0), Duration.FromMinutes(15)); // shift 2 Shift shift2 = schedule.CreateShift("Shift2", "Shift #2", shift2Start, shiftDuration); // shift 1, 5 days ON, 2 OFF Rotation rotation1 = schedule.CreateRotation("Shift1", "Shift1"); rotation1.AddSegment(shift1, 5, 2); // shift 2, 5 days ON, 2 OFF Rotation rotation2 = schedule.CreateRotation("Shift2", "Shift2"); rotation2.AddSegment(shift2, 5, 2); LocalDate startRotation = new LocalDate(2016, 1, 1); Team team1 = schedule.CreateTeam("Team1", "Team #1", rotation1, startRotation); Team team2 = schedule.CreateTeam("Team2", "Team #2", rotation2, startRotation); // same day LocalDateTime from = startRotation.PlusDays(7).At(shift1Start); LocalDateTime to; Duration totalWorking = Duration.Zero; // 21 days, team1 Duration d = Duration.Zero; for (int i = 0; i < 21; i++) { to = from.PlusDays(i); totalWorking = team1.CalculateWorkingTime(from, to); int dir = team1.GetDayInRotation(to.Date); Assert.IsTrue(totalWorking.Equals(d)); TimePeriod period = rotation1.GetPeriods()[dir - 1]; if (period is Shift) { d = d.Plus(shiftDuration); } } Duration totalSchedule = totalWorking; // 21 days, team2 from = startRotation.PlusDays(7).At(shift2Start); d = Duration.Zero; for (int i = 0; i < 21; i++) { to = from.PlusDays(i); totalWorking = team2.CalculateWorkingTime(from, to); int dir = team2.GetDayInRotation(to.Date); Assert.IsTrue(totalWorking.Equals(d)); if (rotation1.GetPeriods()[dir - 1] is Shift) { d = d.Plus(shiftDuration); } } totalSchedule = totalSchedule.Plus(totalWorking); Duration scheduleDuration = schedule.CalculateWorkingTime(from, from.PlusDays(21)); Duration nonWorkingDuration = schedule.CalculateNonWorkingTime(from, from.PlusDays(21)); Assert.IsTrue(scheduleDuration.Plus(nonWorkingDuration).Equals(totalSchedule)); // breaks Duration allBreaks = Duration.FromMinutes(90); Assert.IsTrue(shift1.CalculateBreakTime().Equals(allBreaks)); // misc WorkSchedule schedule2 = new WorkSchedule(); Shift shift3 = new Shift(); shift3.Name = "Shift3"; Assert.IsTrue(shift3.WorkSchedule == null); Assert.IsTrue(shift3.CompareTo(shift3) == 0); Team team3 = new Team(); Assert.IsTrue(team3.WorkSchedule == null); RotationSegment segment = new RotationSegment(); segment.Sequence = 1; segment.StartingShift = shift2; segment.DaysOn = 5; segment.DaysOff = 2; Assert.IsTrue(segment.Rotation == null); Rotation rotation3 = new Rotation(); rotation3.Name = "Rotation3"; Assert.IsTrue(rotation3.CompareTo(rotation3) == 0); Assert.IsTrue(rotation3.RotationSegments.Count == 0); NonWorkingPeriod nwp = new NonWorkingPeriod(); Assert.IsTrue(nwp.WorkSchedule == null); Assert.IsTrue(team1.WorkSchedule.Equals(schedule)); Assert.IsTrue(!team1.IsDayOff(startRotation)); Assert.IsTrue(team1.CompareTo(team1) == 0); team3.Rotation = rotation1; Assert.IsTrue(!memorialDay.IsInPeriod(new LocalDate(2016, 1, 1))); RunBaseTest(schedule, Duration.FromHours(40), Duration.FromDays(7), new LocalDate(2016, 1, 1)); }
public void TestExceptions() { schedule = new WorkSchedule("Exceptions", "Test exceptions"); Duration shiftDuration = Duration.FromHours(24); LocalTime shiftStart = new LocalTime(7, 0, 0); NonWorkingPeriod period = schedule.CreateNonWorkingPeriod("Non-working", "Non-working period", new LocalDateTime(2017, 1, 1, 0, 0, 0), Duration.FromHours(24)); try { period.Duration = Duration.FromSeconds(0); Assert.Fail(); } catch (Exception) { } try { // same period schedule.CreateNonWorkingPeriod("Non-working", "Non-working period", new LocalDateTime(2017, 1, 1, 0, 0, 0), Duration.FromHours(24)); Assert.Fail(); } catch (Exception) { } // shift Shift shift = schedule.CreateShift("Test", "Test shift", shiftStart, shiftDuration); try { // crosses midnight shift.CalculateWorkingTime(shiftStart.Minus(Period.FromHours(1)), shift.GetEnd().PlusHours(1)); Assert.Fail(); } catch (Exception) { } try { shift.Duration = Duration.FromSeconds(0); Assert.Fail(); } catch (Exception) { } try { shift.Duration = Duration.FromSeconds(48 * 3600); Assert.Fail(); } catch (Exception) { } try { // same shift shift = schedule.CreateShift("Test", "Test shift", shiftStart, shiftDuration); Assert.Fail(); } catch (Exception) { } Rotation rotation = schedule.CreateRotation("Rotation", "Rotation"); rotation.AddSegment(shift, 5, 2); LocalDate startRotation = new LocalDate(2016, 12, 31); Team team = schedule.CreateTeam("Team", "Team", rotation, startRotation); // ok schedule.CalculateWorkingTime(new LocalDateTime(2017, 1, 1, 7, 0, 0), new LocalDateTime(2017, 2, 1, 0, 0, 0)); try { // end before start schedule.CalculateWorkingTime(new LocalDateTime(2017, 1, 2, 0, 0, 0), new LocalDateTime(2017, 1, 1, 0, 0, 0)); Assert.Fail(); } catch (Exception) { } try { // same team team = schedule.CreateTeam("Team", "Team", rotation, startRotation); Assert.Fail(); } catch (Exception) { } try { // date before start team.GetDayInRotation(new LocalDate(2016, 1, 1)); Assert.Fail(); } catch (Exception) { } try { // end before start schedule.PrintShiftInstances(new LocalDate(2017, 1, 2), new LocalDate(2017, 1, 1)); Assert.Fail(); } catch (Exception) { } try { // delete in-use shift schedule.DeleteShift(shift); Assert.Fail(); } catch (Exception) { } // breaks Break lunch = shift.CreateBreak("Lunch", "Lunch", new LocalTime(12, 0, 0), Duration.FromMinutes(60)); lunch.Duration = Duration.FromMinutes(30); lunch.StartTime = new LocalTime(11, 30, 0); shift.RemoveBreak(lunch); shift.RemoveBreak(lunch); Shift shift2 = schedule.CreateShift("Test2", "Test shift2", shiftStart, shiftDuration); Assert.IsFalse(shift.Equals(shift2)); Break lunch2 = shift2.CreateBreak("Lunch2", "Lunch", new LocalTime(12, 0, 0), Duration.FromMinutes(60)); shift.RemoveBreak(lunch2); // ok to delete WorkSchedule schedule2 = new WorkSchedule("Exceptions2", "Test exceptions2"); schedule2.Name = "Schedule 2"; schedule2.Description = "a description"; schedule2.DeleteShift(shift); schedule2.DeleteTeam(team); schedule2.DeleteNonWorkingPeriod(period); // nulls try { schedule.CreateShift(null, "1", shiftStart, Duration.FromMinutes(60)); Assert.Fail(); } catch (Exception) { } Assert.IsFalse(shift.Equals(rotation)); // hashcode() team.GetHashCode(); String name = team.Name; Dictionary <String, Team> teams = new Dictionary <String, Team>(); teams[name] = team; Team t = teams[name]; }
public void TestTeamWorkingTime() { schedule = new WorkSchedule("Team Working Time", "Test team working time"); Duration shiftDuration = Duration.FromHours(12); Duration halfShift = Duration.FromHours(6); LocalTime shiftStart = new LocalTime(7, 0, 0); Shift shift = schedule.CreateShift("Team Shift1", "Team shift 1", shiftStart, shiftDuration); Rotation rotation = schedule.CreateRotation("Team", "Rotation"); rotation.AddSegment(shift, 1, 1); LocalDate startRotation = new LocalDate(2017, 1, 1); Team team = schedule.CreateTeam("Team", "Team", rotation, startRotation); team.RotationStart = startRotation; // case #1 LocalDateTime from = startRotation.PlusDays(rotation.GetDayCount()).At(shiftStart); LocalDateTime to = from.PlusDays(1); Duration time = team.CalculateWorkingTime(from, to); Assert.IsTrue(time.Equals(shiftDuration)); // case #2 to = from.PlusDays(2); time = team.CalculateWorkingTime(from, to); Assert.IsTrue(time.Equals(shiftDuration)); // case #3 to = from.PlusDays(3); time = team.CalculateWorkingTime(from, to); Assert.IsTrue(time.Equals(shiftDuration.Plus(shiftDuration))); // case #4 to = from.PlusDays(4); time = team.CalculateWorkingTime(from, to); Assert.IsTrue(time.Equals(shiftDuration.Plus(shiftDuration))); // case #5 from = startRotation.PlusDays(rotation.GetDayCount()).At(shiftStart.PlusHours(6)); to = from.PlusDays(1); time = team.CalculateWorkingTime(from, to); Assert.IsTrue(time.Equals(halfShift)); // case #6 to = from.PlusDays(2); time = team.CalculateWorkingTime(from, to); Assert.IsTrue(time.Equals(shiftDuration)); // case #7 to = from.PlusDays(3); time = team.CalculateWorkingTime(from, to); Assert.IsTrue(time.Equals(shiftDuration.Plus(halfShift))); // case #8 to = from.PlusDays(4); time = team.CalculateWorkingTime(from, to); Assert.IsTrue(time.Equals(shiftDuration.Plus(shiftDuration))); // now crossing midnight shiftStart = new LocalTime(18, 0, 0); Shift shift2 = schedule.CreateShift("Team Shift2", "Team shift 2", shiftStart, shiftDuration); Rotation rotation2 = schedule.CreateRotation("Case 8", "Case 8"); rotation2.AddSegment(shift2, 1, 1); Team team2 = schedule.CreateTeam("Team2", "Team 2", rotation2, startRotation); team2.RotationStart = startRotation; // case #1 from = startRotation.PlusDays(rotation.GetDayCount()).At(shiftStart); to = from.PlusDays(1); time = team2.CalculateWorkingTime(from, to); Assert.IsTrue(time.Equals(shiftDuration)); // case #2 to = from.PlusDays(2); time = team2.CalculateWorkingTime(from, to); Assert.IsTrue(time.Equals(shiftDuration)); // case #3 to = from.PlusDays(3); time = team2.CalculateWorkingTime(from, to); Assert.IsTrue(time.Equals(shiftDuration.Plus(shiftDuration))); // case #4 to = from.PlusDays(4); time = team2.CalculateWorkingTime(from, to); Assert.IsTrue(time.Equals(shiftDuration.Plus(shiftDuration))); // case #5 from = startRotation.PlusDays(rotation.GetDayCount()).At(LocalTime.MaxValue); to = from.PlusDays(1); time = team2.CalculateWorkingTime(from, to); Assert.IsTrue(time.Equals(halfShift)); // case #6 to = from.PlusDays(2); time = team2.CalculateWorkingTime(from, to); Assert.IsTrue(time.Equals(shiftDuration)); // case #7 to = from.PlusDays(3); time = team2.CalculateWorkingTime(from, to); Assert.IsTrue(time.Equals(shiftDuration.Plus(halfShift))); // case #8 to = from.PlusDays(4); time = team2.CalculateWorkingTime(from, to); Assert.IsTrue(time.Equals(shiftDuration.Plus(shiftDuration))); }
public void Test21TeamFixed() { string description = "This plan is a fixed (no rotation) plan that uses 21 teams and three 8-hr shifts to provide 24/7 coverage. " + "It maximizes the number of consecutive days off while still averaging 40 hours per week. " + "Over a 7 week cycle, each employee has two 3 consecutive days off and is required to work 6 consecutive days on 5 of the 7 weeks. " + "On any given day, 15 teams will be scheduled to work and 6 teams will be off. " + "Each shift will be staffed by 5 teams so the minimum number of employees per shift is five. "; schedule = new WorkSchedule("21 Team Fixed 8 6D Plan", description); // Day shift, starts at 07:00 for 8 hours Shift day = schedule.CreateShift("Day", "Day shift", new LocalTime(7, 0, 0), Duration.FromHours(8)); // Swing shift, starts at 15:00 for 8 hours Shift swing = schedule.CreateShift("Swing", "Swing shift", new LocalTime(15, 0, 0), Duration.FromHours(8)); // Night shift, starts at 15:00 for 8 hours Shift night = schedule.CreateShift("Night", "Night shift", new LocalTime(23, 0, 0), Duration.FromHours(8)); // day rotation Rotation dayRotation = schedule.CreateRotation("Day", "Day"); dayRotation.AddSegment(day, 6, 3); dayRotation.AddSegment(day, 5, 3); dayRotation.AddSegment(day, 6, 2); dayRotation.AddSegment(day, 6, 2); dayRotation.AddSegment(day, 6, 2); dayRotation.AddSegment(day, 6, 2); // swing rotation Rotation swingRotation = schedule.CreateRotation("Swing", "Swing"); swingRotation.AddSegment(swing, 6, 3); swingRotation.AddSegment(swing, 5, 3); swingRotation.AddSegment(swing, 6, 2); swingRotation.AddSegment(swing, 6, 2); swingRotation.AddSegment(swing, 6, 2); swingRotation.AddSegment(swing, 6, 2); // night rotation Rotation nightRotation = schedule.CreateRotation("Night", "Night"); nightRotation.AddSegment(night, 6, 3); nightRotation.AddSegment(night, 5, 3); nightRotation.AddSegment(night, 6, 2); nightRotation.AddSegment(night, 6, 2); nightRotation.AddSegment(night, 6, 2); nightRotation.AddSegment(night, 6, 2); // day teams schedule.CreateTeam("Team 1", "1st day team", dayRotation, referenceDate); schedule.CreateTeam("Team 2", "2nd day team", dayRotation, referenceDate.PlusDays(7)); schedule.CreateTeam("Team 3", "3rd day team", dayRotation, referenceDate.PlusDays(14)); schedule.CreateTeam("Team 4", "4th day team", dayRotation, referenceDate.PlusDays(21)); schedule.CreateTeam("Team 5", "5th day team", dayRotation, referenceDate.PlusDays(28)); schedule.CreateTeam("Team 6", "6th day team", dayRotation, referenceDate.PlusDays(35)); schedule.CreateTeam("Team 7", "7th day team", dayRotation, referenceDate.PlusDays(42)); // swing teams schedule.CreateTeam("Team 8", "1st swing team", swingRotation, referenceDate); schedule.CreateTeam("Team 9", "2nd swing team", swingRotation, referenceDate.PlusDays(7)); schedule.CreateTeam("Team 10", "3rd swing team", swingRotation, referenceDate.PlusDays(14)); schedule.CreateTeam("Team 11", "4th swing team", swingRotation, referenceDate.PlusDays(21)); schedule.CreateTeam("Team 12", "5th swing team", swingRotation, referenceDate.PlusDays(28)); schedule.CreateTeam("Team 13", "6th swing team", swingRotation, referenceDate.PlusDays(35)); schedule.CreateTeam("Team 14", "7th swing team", swingRotation, referenceDate.PlusDays(42)); // night teams schedule.CreateTeam("Team 15", "1st night team", nightRotation, referenceDate); schedule.CreateTeam("Team 16", "2nd night team", nightRotation, referenceDate.PlusDays(7)); schedule.CreateTeam("Team 17", "3rd night team", nightRotation, referenceDate.PlusDays(14)); schedule.CreateTeam("Team 18", "4th night team", nightRotation, referenceDate.PlusDays(21)); schedule.CreateTeam("Team 19", "5th night team", nightRotation, referenceDate.PlusDays(28)); schedule.CreateTeam("Team 20", "6th night team", nightRotation, referenceDate.PlusDays(35)); schedule.CreateTeam("Team 21", "7th night team", nightRotation, referenceDate.PlusDays(42)); RunBaseTest(schedule, Duration.FromHours(280), Duration.FromDays(49), referenceDate.PlusDays(49)); }
public void TestNonWorkingTime() { schedule = new WorkSchedule("Non Working Time", "Test non working time"); LocalDate date = new LocalDate(2017, 1, 1); LocalTime time = new LocalTime(7, 0, 0); NonWorkingPeriod period1 = schedule.CreateNonWorkingPeriod("Day1", "First test day", date.At(LocalTime.Midnight), Duration.FromHours(24)); NonWorkingPeriod period2 = schedule.CreateNonWorkingPeriod("Day2", "First test day", date.PlusDays(7).At(time), Duration.FromHours(24)); LocalDateTime from = date.At(time); LocalDateTime to = date.At(time.PlusHours(1)); // case #1 Duration duration = schedule.CalculateNonWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(1))); // case #2 from = date.Minus(Period.FromDays(1)).At(time); to = date.PlusDays(1).At(time); duration = schedule.CalculateNonWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(24))); // case #3 from = date.Minus(Period.FromDays(1)).At(time); to = date.Minus(Period.FromDays(1)).At(time.PlusHours(1)); duration = schedule.CalculateNonWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(0))); // case #4 from = date.PlusDays(1).At(time); to = date.PlusDays(1).At(time.PlusHours(1)); duration = schedule.CalculateNonWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(0))); // case #5 from = date.Minus(Period.FromDays(1)).At(time); to = date.At(time); duration = schedule.CalculateNonWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(7))); // case #6 from = date.At(time); to = date.PlusDays(1).At(time); duration = schedule.CalculateNonWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(17))); // case #7 from = date.At(LocalTime.Noon); to = date.PlusDays(7).At(LocalTime.Noon); duration = schedule.CalculateNonWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(17))); // case #8 from = date.Minus(Period.FromDays(1)).At(LocalTime.Noon); to = date.PlusDays(8).At(LocalTime.Noon); duration = schedule.CalculateNonWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(48))); // case #9 schedule.DeleteNonWorkingPeriod(period1); schedule.DeleteNonWorkingPeriod(period2); from = date.At(time); to = date.At(time.PlusHours(1)); // case #10 duration = schedule.CalculateNonWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(0))); Duration shiftDuration = Duration.FromHours(8); LocalTime shiftStart = new LocalTime(7, 0, 0); Shift shift = schedule.CreateShift("Work Shift1", "Working time shift", shiftStart, shiftDuration); Rotation rotation = schedule.CreateRotation("Case 10", "Case10"); rotation.AddSegment(shift, 1, 1); LocalDate startRotation = new LocalDate(2017, 1, 1); Team team = schedule.CreateTeam("Team", "Team", rotation, startRotation); team.RotationStart = startRotation; period1 = schedule.CreateNonWorkingPeriod("Day1", "First test day", date.At(LocalTime.Midnight), Duration.FromHours(24)); LocalDate mark = date.PlusDays(rotation.GetDayCount()); from = mark.At(time.Minus(Period.FromHours(2))); to = mark.At(time.Minus(Period.FromHours(1))); // case #11 duration = schedule.CalculateWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(0))); // case #12 from = date.At(shiftStart); to = date.At(time.PlusHours(8)); duration = schedule.CalculateNonWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(8))); }
public void TestTeamWorkingTime2() { schedule = new WorkSchedule("4 Team Plan", "test schedule"); // Day shift #1, starts at 07:00 for 15.5 hours Shift crossover = schedule.CreateShift("Crossover", "Day shift #1 cross-over", new LocalTime(7, 0, 0), Duration.FromHours(15).Plus(Duration.FromMinutes(30))); // Day shift #2, starts at 07:00 for 14 hours Shift day = schedule.CreateShift("Day", "Day shift #2", new LocalTime(7, 0, 0), Duration.FromHours(14)); // Night shift, starts at 22:00 for 14 hours Shift night = schedule.CreateShift("Night", "Night shift", new LocalTime(22, 0, 0), Duration.FromHours(14)); // Team 4-day rotation Rotation rotation = schedule.CreateRotation("4 Team", "4 Team"); rotation.AddSegment(day, 1, 0); rotation.AddSegment(crossover, 1, 0); rotation.AddSegment(night, 1, 1); Team team1 = schedule.CreateTeam("Team 1", "First team", rotation, referenceDate); // partial in Day 1 LocalTime am7 = new LocalTime(7, 0, 0); LocalDate testStart = referenceDate.PlusDays(rotation.GetDayCount()); LocalDateTime from = testStart.At(am7); LocalDateTime to = testStart.At(am7.PlusHours(1)); //------------------------------------------------------------------ // from first day in rotation for Team1 from = testStart.At(LocalTime.Midnight); to = testStart.At(LocalTime.MaxValue); Duration duration = team1.CalculateWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(14))); to = testStart.PlusDays(1).At(LocalTime.MaxValue); duration = team1.CalculateWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(29).Plus(Duration.FromMinutes(30)))); to = testStart.PlusDays(2).At(LocalTime.MaxValue); duration = team1.CalculateWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(31).Plus(Duration.FromMinutes(30)))); to = testStart.PlusDays(3).At(LocalTime.MaxValue); duration = team1.CalculateWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(43).Plus(Duration.FromMinutes(30)))); to = testStart.PlusDays(4).At(LocalTime.MaxValue); duration = team1.CalculateWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(57).Plus(Duration.FromMinutes(30)))); to = testStart.PlusDays(5).At(LocalTime.MaxValue); duration = team1.CalculateWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(73))); to = testStart.PlusDays(6).At(LocalTime.MaxValue); duration = team1.CalculateWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(75))); to = testStart.PlusDays(7).At(LocalTime.MaxValue); duration = team1.CalculateWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(87))); // from third day in rotation for Team1 from = testStart.PlusDays(2).At(LocalTime.Midnight); to = testStart.PlusDays(2).At(LocalTime.MaxValue); duration = team1.CalculateWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(2))); to = testStart.PlusDays(3).At(LocalTime.MaxValue); duration = team1.CalculateWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(14))); to = testStart.PlusDays(4).At(LocalTime.MaxValue); duration = team1.CalculateWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(28))); to = testStart.PlusDays(5).At(LocalTime.MaxValue); duration = team1.CalculateWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(43).Plus(Duration.FromMinutes(30)))); to = testStart.PlusDays(6).At(LocalTime.MaxValue); duration = team1.CalculateWorkingTime(from, to); Assert.IsTrue(duration.Equals(Duration.FromHours(45).Plus(Duration.FromMinutes(30)))); }