问题
I implemented the below RandomDate, but I always keep getting values closed to "From" date, i probably miss something here....
public static DateTime GetRandomDate(DateTime from, DateTime to)
{
var range = new TimeSpan(to.Ticks - from.Ticks);
var rnd = new Random();
var randTimeSpan = new TimeSpan((long)(range.TotalSeconds - rnd.Next(0, (int)range.TotalSeconds)));
return from + randTimeSpan;
}
回答1:
You could change to:
static readonly Random rnd = new Random();
public static DateTime GetRandomDate(DateTime from, DateTime to)
{
var range = to - from;
var randTimeSpan = new TimeSpan((long)(rnd.NextDouble() * range.Ticks));
return from + randTimeSpan;
}
Explanation: I used NextDouble()
because it gives a number between 0.0
and 1.0
. Your return value won't be a whole number of seconds in my solution. And I moved rnd
out to a field on the class/struct. Because it's best to reuse one Random
instance, and not create a new one every time one needs just one additional random number.
回答2:
The problem is that:
var randTimeSpan = new TimeSpan((long)(range.TotalSeconds - rnd.Next(0, (int)range.TotalSeconds)));
is creating a TimeSpan from TICKS, not from SECONDS.
You need:
var randTimeSpan = TimeSpan.FromSeconds((long)(range.TotalSeconds - rnd.Next(0, (int)range.TotalSeconds)));
(Please check the cast too - it needs to be a double passed to FromSeconds)
回答3:
This is because TimeSpan's constructor that takes a long expects ticks, not seconds.
var randTimeSpan = new TimeSpan(range.Ticks - rnd.Next(0, range.Ticks));
回答4:
Fixed ArgumentOutOfRangeException:
public static DateTime GetRandomDateTime(DateTime? min = null, DateTime? max = null)
{
min = min ?? new DateTime(1753, 01, 01);
max = max ?? new DateTime(9999, 12, 31);
var range = max.Value - min.Value;
var randomUpperBound = (Int32) range.TotalSeconds;
if (randomUpperBound <= 0)
randomUpperBound = Rnd.Next(1, Int32.MaxValue);
var randTimeSpan = TimeSpan.FromSeconds((Int64) (range.TotalSeconds - Rnd.Next(0, randomUpperBound)));
return min.Value.Add(randTimeSpan);
}
回答5:
This is working for me. The days interval is until 28 to avoid the exception with February.
Random r = new Random();
DateTime rDate = new DateTime(r.Next(1900, 2010), r.Next(1, 12), r.Next(1, 28));
回答6:
My idea is we just need some random number of ticks added to start datetime to get a random date in between start and end. So my solution does not create any TimeSpan
objects.
private static readonly Random random = new Random ();
private static readonly object syncLock = new object ();
public static DateTime RandomDate(DateTime from, DateTime to)
{
lock ( syncLock )
{
return from.AddTicks ((long) ( random.NextDouble () * ( to.Ticks - from.Ticks ) ));
}
}
来源:https://stackoverflow.com/questions/14505932/random-datetime-between-range-not-unified-output