What's the best practice for getting a random DateTime between two date-times?
You could try using:
var randomTest = new Random();
TimeSpan timeSpan = endDate - startDate;
TimeSpan newSpan = new TimeSpan(0, randomTest.Next(0, (int)timeSpan.TotalMinutes), 0);
DateTime newDate = startDate + newSpan;
This will give you different times down to the minute. If you want 100 (or any thing more than 1) DateTime
s then only create the Random
object once. The MSDN page on Random
explains in detail why creating several Random
objects in quick succession is a bad idea.
Using a different TimeSpan
constructor will give you different granularity. From the TimeSpan constructor MSDN:
TimeSpan(Int64) Initializes a new TimeSpan to the specified number of ticks.
TimeSpan(Int32, Int32, Int32) Initializes a new TimeSpan to a specified number of hours, minutes, and seconds.
TimeSpan(Int32, Int32, Int32, Int32) Initializes a new TimeSpan to a specified number of days, hours, minutes, and seconds.
TimeSpan(Int32, Int32, Int32, Int32, Int32) Initializes a new TimeSpan to a specified number of days, hours, minutes, seconds, and milliseconds.
Here's my algorithm and code:
- find the difference between the two dates
- for each iteration, create a random number between the two dates
create a new date between them. Simply add that random number as minutes to the start datetime.
Random randNum = new Random(); DateTime minDt = new DateTime(2000,1,1,10,0,0); DateTime maxDt = new DateTime(2000,1,1,17,0,0); List<DateTime> myDates = new List<DateTime>(); //Random.Next in .NET is non-inclusive to the upper bound (@NickLarsen) int minutesDiff = Convert.ToInt32(maxDt.Subtract(minDt).TotalMinutes+1); for (int i = 0; i < 100; i++) { // some random number that's no larger than minutesDiff, no smaller than 1 int r= randNum.Next(1, minutesDiff); myDates.Add(minDt.AddMinutes(r)); } foreach (DateTime d in myDates) { Console.WriteLine(string.Format("{0:dd-MMM-yyyy hh:mm}",d)); }
This is what I'm using:
class RandomDates
{
private Random random = new Random();
public DateTime Date(DateTime? start = null, DateTime? end = null)
{
if (start.HasValue && end.HasValue && start.Value >= end.Value)
throw new Exception("start date must be less than end date!");
DateTime min = start ?? DateTime.MinValue;
DateTime max = end ?? DateTime.MaxValue;
// for timespan approach see: http://stackoverflow.com/q/1483670/1698987
TimeSpan timeSpan = max - min;
// for random long see: http://stackoverflow.com/a/677384/1698987
byte[] bytes = new byte[8];
random.NextBytes(bytes);
long int64 = Math.Abs(BitConverter.ToInt64(bytes, 0)) % timeSpan.Ticks;
TimeSpan newSpan = new TimeSpan(int64);
return min + newSpan;
}
}
I used the approach in the accepted answer but modified it slightly as I had issues with it.