/// <summary> /// Generates a random <see cref="DateTime"></see> object based on the specified date range /// </summary> /// <param name="start">DateTime range start</param> /// <param name="end">DateTime range end</param> /// <param name="minuteRounding">Rounds time to the specified minute rounding</param> /// <param name="secondRounding">Rounds time to the specified second rounding</param> /// <param name="workingHours">Limits the time range between 8am and 6pm - Monday to Friday</param> /// <returns></returns> public static DateTime WithinRange(DateTime start, DateTime end, MinuteRounding minuteRounding = MinuteRounding.None, SecondRounding secondRounding = SecondRounding.None, bool workingHours = false) { // Assertions if (start > end) throw new ArgumentException("End date must be greater than Start"); if (minuteRounding == MinuteRounding.HalfHour && (end - start) < TimeSpan.FromMinutes(30)) throw new ArgumentException("Range must be greater than 30 minutes"); if (minuteRounding == MinuteRounding.QuarterHour && (end - start) < TimeSpan.FromMinutes(15)) throw new ArgumentException("Range must be greater than 15 minutes"); // If the range falls outside of working hours, then throw an error if (workingHours && end - start < TimeSpan.FromDays(1) && start.Intersects(start.Date.Add(WorkingDayStart), start.Date.Add(WorkingDayEnd), end - start)) throw new ArgumentException("Range falls outside of working hours"); // Create random date DateTime date; int counter = 0; do { date = new DateTime(LongRandom(start.Ticks, end.Ticks)); if (minuteRounding != MinuteRounding.None) date = date.RoundMinutes(minuteRounding); if (secondRounding != SecondRounding.None) date = date.RoundSeconds(secondRounding); if (workingHours) date = LimitToWorkingHours(date); counter++; if (counter > 100) throw new Exception("Could not create a DateTime within the specified range. Try using a larger range."); } while (date < start || date > end); return date; }
/// <summary> /// Creates a random <see cref="DateTime"></see> within the specified Day /// </summary> /// <param name="date"></param> /// <returns></returns> public DateTime Create(DateTime date) { if (DaysToExlude.Any(d => d == date.DayOfWeek)) throw new ArgumentException("Invalid DayOfWeek - remove specified DayOfWeek from the DaysToExclude list"); if (DayStart >= DayEnd || DayEnd == TimeSpan.Zero) throw new ArgumentException("Invalid time range - DayEnd must be greater than DayStart"); var validate = new Func<DateTime, bool>((d) => { if (d < date.Date || d > date.Date.AddDays(1)) return false; return true; }); var newDate = date.Date; // Remove the Time component from the Date do { newDate = new DateTime(LongRandom(newDate.Add(DayStart).Ticks, newDate.Add(DayEnd).Ticks), DateTimeKind.Utc); newDate = GetRandomValidTimeInDay(newDate); if (MinuteRoundingMode != MinuteRounding.None) newDate = newDate.RoundMinutes(MinuteRoundingMode); if (SecondRoundingMode != SecondRounding.None) newDate = newDate.RoundSeconds(SecondRoundingMode); } while (!validate(newDate)); return newDate; }