/// <summary> /// Get the ShiftInstance for the specified day /// </summary> /// <param name="day">Date</param> /// <returns>Shift instance</returns> public ShiftInstance GetShiftInstanceForDay(LocalDate day) { ShiftInstance instance = null; Rotation shiftRotation = Rotation; int dayInRotation = GetDayInRotation(day); // shift or off shift TimePeriod period = shiftRotation.GetPeriods()[dayInRotation - 1]; if (period.IsWorkingPeriod()) { LocalDateTime startDateTime = day.At(period.StartTime); instance = new ShiftInstance((Shift)period, startDateTime, this); } return(instance); }
/// <summary> /// Get the list of shift instances for the specified date that start in that date /// </summary> /// <param name="day">Date</param> /// <returns>List of shift instances</returns> public List <ShiftInstance> GetShiftInstancesForDay(LocalDate day) { List <ShiftInstance> workingShifts = new List <ShiftInstance>(); // for each team see if there is a working shift foreach (Team team in Teams) { ShiftInstance instance = team.GetShiftInstanceForDay(day); if (instance == null) { continue; } // check to see if this is a non-working day bool addShift = true; LocalDate startDate = instance.StartDateTime.Date; foreach (NonWorkingPeriod nonWorkingPeriod in NonWorkingPeriods) { if (nonWorkingPeriod.IsInPeriod(startDate)) { addShift = false; break; } } if (addShift) { workingShifts.Add(instance); } } workingShifts.Sort(); return(workingShifts); }
/// <summary> /// Calculate the schedule working time between the specified dates and times /// </summary> /// <param name="from">Starting date and time</param> /// <param name="to">Ending date and time</param> /// <returns>Duration</returns> public Duration CalculateWorkingTime(LocalDateTime from, LocalDateTime to) { if (from.CompareTo(to) > 0) { string msg = string.Format(WorkSchedule.GetMessage("end.earlier.than.start"), to, from); throw new Exception(msg); } Duration sum = Duration.Zero; LocalDate thisDate = from.Date; LocalTime thisTime = from.TimeOfDay; LocalDate toDate = to.Date; LocalTime toTime = to.TimeOfDay; int dayCount = Rotation.GetDayCount(); // get the working shift from yesterday Shift lastShift = null; LocalDate yesterday = thisDate.PlusDays(-1); ShiftInstance yesterdayInstance = GetShiftInstanceForDay(yesterday); if (yesterdayInstance != null) { lastShift = yesterdayInstance.Shift; } // step through each day until done while (thisDate.CompareTo(toDate) < 1) { if (lastShift != null && lastShift.SpansMidnight()) { // check for days in the middle of the time period bool lastDay = thisDate.CompareTo(toDate) == 0 ? true : false; if (!lastDay || (lastDay && !toTime.Equals(LocalTime.Midnight))) { // add time after midnight in this day int afterMidnightSecond = TimePeriod.SecondOfDay(lastShift.GetEnd()); int fromSecond = TimePeriod.SecondOfDay(thisTime); if (afterMidnightSecond > fromSecond) { Duration seconds = Duration.FromSeconds(afterMidnightSecond - fromSecond); sum = sum.Plus(seconds); } } } // today's shift ShiftInstance instance = GetShiftInstanceForDay(thisDate); Duration duration; if (instance != null) { lastShift = instance.Shift; // check for last date if (thisDate.CompareTo(toDate) == 0) { duration = lastShift.CalculateWorkingTime(thisTime, toTime, true); } else { duration = lastShift.CalculateWorkingTime(thisTime, LocalTime.MaxValue, true); } sum = sum.Plus(duration); } else { lastShift = null; } int n = 1; if (GetDayInRotation(thisDate) == dayCount) { // move ahead by the rotation count if possible LocalDate rotationEndDate = thisDate.PlusDays(dayCount); if (rotationEndDate.CompareTo(toDate) < 0) { n = dayCount; sum = sum.Plus(Rotation.GetWorkingTime()); } } // move ahead n days starting at midnight thisDate = thisDate.PlusDays(n); thisTime = LocalTime.Midnight; } // end day loop return(sum); }