/// <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); }
internal ShiftInstance(Shift shift, LocalDateTime startDateTime, Team team) { this.Shift = shift; this.StartDateTime = startDateTime; this.Team = team; }