示例#1
0
        /// <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>
        /// Rounds the minute component to the nearest specified time. Defaults to 1 hour
        /// </summary>
        /// <param name="source"></param>
        /// <param name="rounding"></param>
        /// <returns></returns>
        public static DateTime RoundMinutes(this DateTime source, MinuteRounding rounding = MinuteRounding.Hour)
        {
            if (rounding == MinuteRounding.QuarterHour)
                throw new NotImplementedException("Coming soon");

            switch (rounding)
            {
                case MinuteRounding.Hour:
                    if (source.Minute >= 30)
                        return source.AddHours(1).AddMinutes(-source.Minute).TrimSeconds();
                    return source.AddMinutes(-source.Minute).TrimSeconds();
                case MinuteRounding.HalfHour:
                    if (source.Minute < 15)
                        return source.AddMinutes(-source.Minute).TrimSeconds();
                    if (source.Minute >= 15 && source.Minute < 45)
                        return source.AddMinutes(-source.Minute).AddMinutes(30).TrimSeconds();
                    return source.AddHours(1).AddMinutes(-source.Minute).TrimSeconds();
                default:
                    throw new ArgumentOutOfRangeException("rounding");
            }
        }