Я шукаю короткий, сучасний код C # для створення випадкової дати між 1 січня 1995 року та поточною датою.
Я думаю, що рішення, яке використовує Enumerable.Range якось може зробити це більш лаконічним.
Я шукаю короткий, сучасний код C # для створення випадкової дати між 1 січня 1995 року та поточною датою.
Я думаю, що рішення, яке використовує Enumerable.Range якось може зробити це більш лаконічним.
Відповіді:
private Random gen = new Random();
DateTime RandomDay()
{
DateTime start = new DateTime(1995, 1, 1);
int range = (DateTime.Today - start).Days;
return start.AddDays(gen.Next(range));
}
Для кращої продуктивності, якщо це буде викликано неодноразово, створіть startі gen(а може, навіть range) змінні за межами функції.
Це є незначною відповіддю на коментар Джоеля щодо створення трохи більш оптимізованої версії. Замість повернення випадкової дати безпосередньо, чому б не повернути функцію генератора, яку можна повторно викликати для створення випадкової дати.
Func<DateTime> RandomDayFunc()
{
DateTime start = new DateTime(1995, 1, 1);
Random gen = new Random();
int range = ((TimeSpan)(DateTime.Today - start)).Days;
return () => start.AddDays(gen.Next(range));
}
for (int i = 0; i < 100; i++) { array[i].DateProp = RandomDayFunc()(); }
var getRandomDate = RandomDayFunc();потім називаєш його, щоб отримати випадкові дати: var randomDate = getRandomDate();Зверніть увагу, що вам потрібно повторно використовувати getRandomDate, щоб це було корисніше, ніж відповідь Джоела.
Я прийняв відповідь @Joel Coehoorn і вніс зміни, які він порадив - вивів змінну з методу і поставив усіх у класі. Плюс зараз час теж випадковий. Ось результат.
class RandomDateTime
{
DateTime start;
Random gen;
int range;
public RandomDateTime()
{
start = new DateTime(1995, 1, 1);
gen = new Random();
range = (DateTime.Today - start).Days;
}
public DateTime Next()
{
return start.AddDays(gen.Next(range)).AddHours(gen.Next(0,24)).AddMinutes(gen.Next(0,60)).AddSeconds(gen.Next(0,60));
}
}
І приклад, як використовувати для написання 100 випадкових DateTimes для консолі:
RandomDateTime date = new RandomDateTime();
for (int i = 0; i < 100; i++)
{
Console.WriteLine(date.Next());
}
range = (int)(DateTime.Today - start).TotalSeconds;і return start.AddSeconds(gen.Next(range));.
Що ж, якщо ви запропонуєте альтернативну оптимізацію, ми також можемо перейти до ітератора:
static IEnumerable<DateTime> RandomDay()
{
DateTime start = new DateTime(1995, 1, 1);
Random gen = new Random();
int range = ((TimeSpan)(DateTime.Today - start)).Days;
while (true)
yield return start.AddDays(gen.Next(range));
}
Ви можете використовувати його так:
int i=0;
foreach(DateTime dt in RandomDay())
{
Console.WriteLine(dt);
if (++i == 10)
break;
}
Почніть з об'єкта з фіксованою датою (1 січня 1995 р.) І додайте випадкову кількість днів за допомогою AddDays (явно зверніть увагу, не перевершуючи поточну дату).
Я трохи запізнююся в грі, але ось одне рішення, яке працює чудово:
void Main()
{
var dateResult = GetRandomDates(new DateTime(1995, 1, 1), DateTime.UtcNow, 100);
foreach (var r in dateResult)
Console.WriteLine(r);
}
public static IList<DateTime> GetRandomDates(DateTime startDate, DateTime maxDate, int range)
{
var randomResult = GetRandomNumbers(range).ToArray();
var calculationValue = maxDate.Subtract(startDate).TotalMinutes / int.MaxValue;
var dateResults = randomResult.Select(s => startDate.AddMinutes(s * calculationValue)).ToList();
return dateResults;
}
public static IEnumerable<int> GetRandomNumbers(int size)
{
var data = new byte[4];
using (var rng = new System.Security.Cryptography.RNGCryptoServiceProvider(data))
{
for (int i = 0; i < size; i++)
{
rng.GetBytes(data);
var value = BitConverter.ToInt32(data, 0);
yield return value < 0 ? value * -1 : value;
}
}
}
Невеликий метод, який повертає випадкову дату як рядок, заснований на деяких простих вхідних параметрах. Побудований на основі варіацій із наведених відповідей:
public string RandomDate(int startYear = 1960, string outputDateFormat = "yyyy-MM-dd")
{
DateTime start = new DateTime(startYear, 1, 1);
Random gen = new Random(Guid.NewGuid().GetHashCode());
int range = (DateTime.Today - start).Days;
return start.AddDays(gen.Next(range)).ToString(outputDateFormat);
}