public double MinutesAbsent(IEnumerable <Presence> presences) { // Given a list of presences, select only those that overlap this block var relevantPresences = Presence.CombineOverlapping( presences?.Where(p => p?.OverlapsWith(this) == true))? .OrderBy(p => p.Arrival) .ToList(); // If there aren't any relevant presences, return the total minutes for this block if (relevantPresences == null || relevantPresences.Count == 0) { return((End - Start).TotalMinutes); } // Get any absent minutes at the start of the block by determining // if the first presence arrived after the block's start. If it did, // begin with the difference between the block's Start and the // first presence's Arrival. var minutesAbsent = relevantPresences.First().Arrival > Start ? (relevantPresences.First().Arrival - Start).TotalMinutes : 0; // Then add the number of minutes between each presence's // Departure and the next presence's Arrival for (var i = 0; i < relevantPresences.Count - 1; i++) { minutesAbsent += (relevantPresences[i + 1].Arrival - relevantPresences[i].Departure).TotalMinutes; } // Finally, add any minutes after the last presence // if it departed before the end of the block if (relevantPresences.Last().Departure < End) { minutesAbsent += (End - relevantPresences.Last().Departure).TotalMinutes; } return(minutesAbsent); }