我正在尝试为简单的DateTime
数据字段随机化值。
我希望获得两个日期/时间之间的随机日期/时间(例如,最小日期/时间和最长日期/时间)。
所以让我们想象一下我之间的随机日期/时间
1/1/2000 10:00:00am
和1/1/2000 5:00:00pm
。
此外,此代码将用于for循环,包含100个项目...意味着所有100个项目将在最小/最大日期/时间段之间具有随机日期/时间。
有什么想法吗?
答案 0 :(得分:36)
您可以尝试使用:
TimeSpan timeSpan = endDate - startDate;
var randomTest = new Random();
TimeSpan newSpan = new TimeSpan(0, randomTest.Next(0, (int)timeSpan.TotalMinutes), 0);
DateTime newDate = startDate + newSpan;
这将为您提供不同的时间。如果您想要100(或任何超过1)DateTime
s,那么只需创建一次Random
对象。 MSDN page on Random
详细解释了为什么快速连续创建多个Random
对象是一个坏主意。
使用不同的TimeSpan
构造函数将为您提供不同的粒度。来自TimeSpan constructor MSDN:
TimeSpan(Int64)将新的TimeSpan初始化为指定的刻度数。
TimeSpan(Int32,Int32,Int32)将新的TimeSpan初始化为指定的小时数,分钟数和秒数。
TimeSpan(Int32,Int32,Int32,Int32)将新的TimeSpan初始化为指定的数量 天,小时,分钟和秒 TimeSpan(Int32,Int32,Int32,Int32,Int32)将新的TimeSpan初始化为指定的天数,小时数,分钟数,秒数和毫秒数。
答案 1 :(得分:4)
这是我的算法和代码:
在它们之间创建一个新日期。只需将该随机数作为分钟添加到开始日期时间。
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));
}
答案 2 :(得分:3)
这就是我正在使用的:
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;
}
}
我在接受的答案中使用了这种方法,但稍微修改了一下,因为我遇到了问题。
答案 3 :(得分:2)
真的很快:
答案 4 :(得分:1)
首先,找出随机DateTime(小时,分钟,秒,ms等)所需的精度。
然后找出该单位中两个日期之间的差异。
创建一个介于0和差异之间的随机整数。
将随机整数以单位添加到原始日期。
根据您上面说明的用例,计算for循环外部的差异。
在for循环中,获取random int并构造随机日期。
答案 5 :(得分:1)
基于ChrisF的解决方案的单行
var newDate = startDate.AddHours(new Random(Convert.ToInt32(DateTime.Now.Ticks / int.MaxValue)).Next(0, (int)(endDate - startDate).TotalHours));
答案 6 :(得分:0)
这是一个使用随机数滴答的方法:
Random r= new Random();
//for better randomness don't recreate a new Random() too frequently.
long rand62bit = (((long)r.Next())<<31) + r.Next();
// 62bits suffices for random datetimes, 31 does not!
DateTime newDate = startDate + new TimeSpan(rand62bit % (endDate - startDate).Ticks);
此方法独占最后一个日期,包含第一个日期。您可以通过在基本(endDate - startDate).Ticks
数量上添加一个勾号来轻松包含最后日期。