I'm trying to randomize the value for a simple DateTime
data field.
我正在尝试随机化一个简单的DateTime数据字段的值。
I wish to get a random date/time between two date/times (e.g. min date/time and max date/time).
我希望获得两个日期/时间之间的随机日期/时间(例如,最小日期/时间和最大日期/时间)。
So lets imagine I'm after a random date/time between
所以让我们想象一下我之间的随机日期/时间
1/1/2000 10:00:00am
and 1/1/2000 5:00:00pm
.
2000年1月1日上午10:00:00和下午1点1点至下午5点00:00。
Also, this code will be used in a for loop, with 100 items ... meaning all 100 items will have random date/times between the min/max date/time period.
此外,此代码将用于for循环,包含100个项目...这意味着所有100个项目将具有最小/最大日期/时间段之间的随机日期/时间。
Any ideas?
7 个解决方案
#1
30
You could try using:
您可以尝试使用:
TimeSpan timeSpan = endDate - startDate;
var randomTest = new Random();
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.
这将为您提供不同的时间。如果您想要100(或任何超过1)DateTimes,那么只需创建一次Random对象。 Random上的MSDN页面详细解释了为什么快速连续创建几个Random对象是一个坏主意。
Using a different TimeSpan
constructor will give you different granularity. From the TimeSpan constructor MSDN:
使用不同的TimeSpan构造函数将为您提供不同的粒度。从TimeSpan构造函数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.TimeSpan(Int64)将新TimeSpan初始化为指定的刻度数。 TimeSpan(Int32,Int32,Int32)将新TimeSpan初始化为指定的小时数,分钟数和秒数。 TimeSpan(Int32,Int32,Int32,Int32)将新TimeSpan初始化为指定的天数,小时数,分钟数和秒数。 TimeSpan(Int32,Int32,Int32,Int32,Int32)将新TimeSpan初始化为指定的天数,小时数,分钟数,秒数和毫秒数。
#2
3
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)); }
找到两个日期之间的差异
对于每次迭代,在两个日期之间创建一个随机数
#3
2
Really quickly:
- convert your dates to TotalHours
- Subtract one number from the other and use Abs to make positive
- Create a random number within the range of 1 and the result of 2. above
- Add the resulting random number of hours back to the earlier of your two dates
将您的日期转换为TotalHours
从另一个数字中减去一个数字并使用Abs来表示正数
创建一个范围为1的随机数和上面的2.的结果
将得到的随机小时数添加回两个日期的较早时间
#4
1
First, figure out what the precision is that you want on random DateTime (hours,minutes,seconds,ms,etc).
首先,找出随机DateTime(小时,分钟,秒,ms等)的精度。
Then figure out the difference between the two dates in that unit.
然后找出该单位中两个日期之间的差异。
Create a random integer between 0 and that difference.
创建0和该差异之间的随机整数。
Add the random integer in units to the original date.
将随机整数以单位添加到原始日期。
Given the use case you stated above, calculate the difference outside in the for loop.
根据您在上面说明的用例,计算for循环外部的差异。
Inside the for loop, get the random int and construct the random date.
在for循环中,获取random int并构造随机日期。
#5
1
A one-liner based on ChrisF's solution
基于ChrisF解决方案的单线程
var newDate = startDate.AddHours(new Random(Convert.ToInt32(DateTime.Now.Ticks / int.MaxValue)).Next(0, (int)(endDate - startDate).TotalHours));
#6
1
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://*.com/q/1483670/1698987
TimeSpan timeSpan = max - min;
// for random long see: http://*.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.
我在接受的答案中使用了这种方法,但稍微修改了一下,因为我遇到了问题。
#7
0
Here's a method using a random number of ticks:
这是一个使用随机数滴答的方法:
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);
This method is exclusive the last date and inclusive the first. You can easily include the last date by adding one tick to the basic (endDate - startDate).Ticks
quantity.
此方法独占最后一个日期,包含第一个日期。您可以通过向基本(endDate - startDate)添加一个刻度来轻松包含最后一个日期.Ticks数量。
#1
30
You could try using:
您可以尝试使用:
TimeSpan timeSpan = endDate - startDate;
var randomTest = new Random();
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.
这将为您提供不同的时间。如果您想要100(或任何超过1)DateTimes,那么只需创建一次Random对象。 Random上的MSDN页面详细解释了为什么快速连续创建几个Random对象是一个坏主意。
Using a different TimeSpan
constructor will give you different granularity. From the TimeSpan constructor MSDN:
使用不同的TimeSpan构造函数将为您提供不同的粒度。从TimeSpan构造函数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.TimeSpan(Int64)将新TimeSpan初始化为指定的刻度数。 TimeSpan(Int32,Int32,Int32)将新TimeSpan初始化为指定的小时数,分钟数和秒数。 TimeSpan(Int32,Int32,Int32,Int32)将新TimeSpan初始化为指定的天数,小时数,分钟数和秒数。 TimeSpan(Int32,Int32,Int32,Int32,Int32)将新TimeSpan初始化为指定的天数,小时数,分钟数,秒数和毫秒数。
#2
3
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)); }
找到两个日期之间的差异
对于每次迭代,在两个日期之间创建一个随机数
#3
2
Really quickly:
- convert your dates to TotalHours
- Subtract one number from the other and use Abs to make positive
- Create a random number within the range of 1 and the result of 2. above
- Add the resulting random number of hours back to the earlier of your two dates
将您的日期转换为TotalHours
从另一个数字中减去一个数字并使用Abs来表示正数
创建一个范围为1的随机数和上面的2.的结果
将得到的随机小时数添加回两个日期的较早时间
#4
1
First, figure out what the precision is that you want on random DateTime (hours,minutes,seconds,ms,etc).
首先,找出随机DateTime(小时,分钟,秒,ms等)的精度。
Then figure out the difference between the two dates in that unit.
然后找出该单位中两个日期之间的差异。
Create a random integer between 0 and that difference.
创建0和该差异之间的随机整数。
Add the random integer in units to the original date.
将随机整数以单位添加到原始日期。
Given the use case you stated above, calculate the difference outside in the for loop.
根据您在上面说明的用例,计算for循环外部的差异。
Inside the for loop, get the random int and construct the random date.
在for循环中,获取random int并构造随机日期。
#5
1
A one-liner based on ChrisF's solution
基于ChrisF解决方案的单线程
var newDate = startDate.AddHours(new Random(Convert.ToInt32(DateTime.Now.Ticks / int.MaxValue)).Next(0, (int)(endDate - startDate).TotalHours));
#6
1
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://*.com/q/1483670/1698987
TimeSpan timeSpan = max - min;
// for random long see: http://*.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.
我在接受的答案中使用了这种方法,但稍微修改了一下,因为我遇到了问题。
#7
0
Here's a method using a random number of ticks:
这是一个使用随机数滴答的方法:
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);
This method is exclusive the last date and inclusive the first. You can easily include the last date by adding one tick to the basic (endDate - startDate).Ticks
quantity.
此方法独占最后一个日期,包含第一个日期。您可以通过向基本(endDate - startDate)添加一个刻度来轻松包含最后一个日期.Ticks数量。