I'm trying to make an extension method that allows me to create a random time between Now and some user requested historical time point in the form of a TimeSpan.
For example : a random time between now and 1 hour ago.
So, I came up with the following Random(..)
extension method.
I thought to make the random seed NOT static, but if i call this method a LOT and QUICKLY (eg. in a loop), then I thought the seed (which is based on time) isn't really random for really fast calls. is that true? (it seems to be, when i check my results)
public static DateTimeOffset Random(this DateTimeOffset value, TimeSpan timeSpan)
{
var random = new Random();
DateTimeOffset minDateTime = value.Subtract(timeSpan);
int range = ((DateTime.Today - minDateTime)).Hours;
return minDateTime.AddHours(random.Next(range));
}
Best Solution
As others have said, the problem is that
new Random()
uses the current time to form the seed, and you're getting the same one lots of times.Basically you want to create relatively few instances. As
Random
isn't thread-safe, you needThreadStatic
orThreadLocal<T>
- the latter is new to .NET 4.0. Here's a sampleStaticRandom
class (using .NET 4.0) which lets you use theInstance
property to get a valid instance for this thread. Note that on type initialization, a counter is set from the current time. This is then used for successive seeds.Then you can just use
StaticRandom.Instance
whenever you need an instance ofRandom
.Now to get back to the original question, it's not entirely clear what your current extension method is doing. Why are you using
DateTime.Today
at all? I suspect you want something like:However, that will give you a completely random time - it's almost bound to be part way through a millisecond, for instance. Is that okay, or do you effectively want it to be an exact number of seconds (or minutes, or hours) based on the original timespan?