/// <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;
        }