// The complement of B, ∁B. Is everything that's outside of B public static TkTimeSet Complement(TkTimeSet set) { IEnumerable <TkInterval> complement(TkTimeSet s) { var t0 = DateTime.MinValue; foreach (var interval in s.GetOrderedIntervals()) { var t1 = interval.start; if ((t0 - t1).Ticks != 0) { var complementInterval = new TkInterval(t0, t1); yield return(complementInterval); } t0 = interval.end; } if ((DateTime.MaxValue - t0).Ticks != 0) { var lastInterval = new TkInterval(t0, DateTime.MaxValue); yield return(lastInterval); } } var complementSet = complement(set).ToArray(); return(new TkTimeSet(complementSet)); }
// A - B equals the intersection between A and the complement of B public static TkTimeSet Difference(TkTimeSet a, TkTimeSet b) { // A - B = A ∩ ∁B var bComplement = Complement(b); var diff = Intersect(a, bComplement); return(diff); }
// Returns 45 hours since we're not excluding the lunch hour public static TkTimeSet WorkWeek(long weekNumber) { var set = new TkTimeSet(new TkInterval[5]); var day = DateTimeExtensions.GetFirstDayOfWeek(weekNumber); for (var i = 0; i < 5; i++) { var workDay = WorkDay(day, TkWorkWeekConfig.Default); set._tkIntervals[i] = workDay; day = day.AddDays(1); } return(set); }
// Does not join overlapping tkIntervals // if an tkInterval in A already contains the space made up by an tkInterval in B, it'll be ignored public static TkTimeSet Union(TkTimeSet a, TkTimeSet b) { if (b.IsNull || b.IsEmpty()) { return(a); } if (a.IsNull || a.IsEmpty()) { return(b); } // The size of the union between a and b will at end be a.count + b.count var union = new TkInterval[a.Count() + b.Count()]; var unionIndex = a.Count(); // Set the union equal to A for (var i = 0; i < a._tkIntervals.Length; i++) { union[i] = a._tkIntervals[i]; } // Only insert tkIntervals from B into the union // if no tkInterval in A claims that space for (var i = 0; i < b._tkIntervals.Length; i++) { var bInterval = b._tkIntervals[i]; var exists = false; for (var j = 0; j < a._tkIntervals.Length; j++) { var aInterval = a._tkIntervals[j]; if (aInterval.Contains(bInterval)) { exists = true; break; } } if (!exists) { union[unionIndex] = bInterval; unionIndex++; } } return(new TkTimeSet(union)); }
public static TkTimeSet Intersect(TkTimeSet first, TkTimeSet second) { IEnumerable <TkInterval> intersect(TkTimeSet a, TkTimeSet b) { int aIndex = 0, bIndex = 0; while (aIndex < a.Count() && bIndex < b.Count()) { var aInterval = a.ElementAt(aIndex); var bInterval = b.ElementAt(bIndex); // If A doesn't contain B if (!aInterval.Overlaps(bInterval)) { if (aInterval < bInterval) { aIndex++; } else { bIndex++; } } // If A contains B, return B else if (aInterval.Encloses(bInterval)) { yield return(bInterval); bIndex++; } // If B contains A, return A else if (bInterval.Encloses(aInterval)) { yield return(aInterval); aIndex++; } // If A and B are separate tkIntervals else { var highestMin = Max(aInterval.start, bInterval.start); var lowestMax = Min(aInterval.end, bInterval.end); var interval = new TkInterval(highestMin, lowestMax); if (interval.Length() > TimeSpan.Zero) { yield return(interval); } if (aInterval < bInterval) { aIndex++; } else { bIndex++; } } } } var intersection = intersect(first, second).ToArray(); return(new TkTimeSet(intersection)); }
public static TkTimeSet Null() { var empty = new TkTimeSet(new TkInterval[0]); return(empty); }