我实现了下面的 RandomDate,但我总是不断获得接近"开始"日期的值,我可能在这里错过了一些东西......
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;
}
您可以更改为:
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;
}
解释:我使用了NextDouble()
,因为它给出了一个介于 0.0
和 1.0
之间的数字。在我的解决方案中,您的返回值不会是整数秒数。我rnd
移到类/结构上的一个字段。因为最好重用一个Random
实例,而不是在每次只需要一个额外的随机数时创建一个新实例。
问题是:
var randTimeSpan = new TimeSpan((long)(range.TotalSeconds - rnd.Next(0, (int)range.TotalSeconds)));
是从即时报价创建时间跨度,而不是从秒创建时间跨度。
你需要:
var randTimeSpan = TimeSpan.FromSeconds((long)(range.TotalSeconds - rnd.Next(0, (int)range.TotalSeconds)));
(也请检查演员表 - 它需要双重传递给 FromSeconds)
这是因为TimeSpan
的构造函数需要long
期望即时报价,而不是秒。
var randTimeSpan = new TimeSpan(range.Ticks - rnd.Next(0, range.Ticks));
修正了参数超出范围异常:
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);
}
我的想法是,我们只需要在开始日期时间中添加一些随机数量的刻度,就可以在开始和结束之间获得一个随机日期。所以我的解决方案不会创建任何TimeSpan
对象。
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 ) ));
}
}