Estou procurando por um código C # moderno e sucinto para gerar uma data aleatória entre 1º de janeiro de 1995 e a data atual.
Estou pensando em alguma solução que utiliza Enumerable.Range de alguma forma pode tornar isso mais sucinto.
Estou procurando por um código C # moderno e sucinto para gerar uma data aleatória entre 1º de janeiro de 1995 e a data atual.
Estou pensando em alguma solução que utiliza Enumerable.Range de alguma forma pode tornar isso mais sucinto.
Respostas:
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));
}
Para um melhor desempenho, se isso for chamado repetidamente, crie as variáveis start
e gen
(e talvez até range
) fora da função.
Isso é uma leve resposta ao comentário de Joel sobre como criar uma versão ligeiramente mais otimizada. Em vez de retornar uma data aleatória diretamente, por que não retornar uma função geradora que pode ser chamada repetidamente para criar uma data aleatória?
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();
depois a chama para obter datas aleatórias: var randomDate = getRandomDate();
lembre-se de que você precisa reutilizar getRandomDate para que isso seja mais útil do que a resposta de Joel.
Peguei a resposta de @Joel Coehoorn e fiz as alterações que ele recomendou - coloque a variável fora do método e coloque tudo na classe. Além disso, agora o tempo também é aleatório. Aqui está o resultado.
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));
}
}
E exemplo como usar para escrever 100 DateTimes aleatórios no console:
RandomDateTime date = new RandomDateTime();
for (int i = 0; i < 100; i++)
{
Console.WriteLine(date.Next());
}
range = (int)(DateTime.Today - start).TotalSeconds;
e return start.AddSeconds(gen.Next(range));
.
Bem, se você apresentar otimização alternativa, também podemos optar por um iterador:
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));
}
você poderia usá-lo assim:
int i=0;
foreach(DateTime dt in RandomDay())
{
Console.WriteLine(dt);
if (++i == 10)
break;
}
Comece com um objeto de data fixa (1 de janeiro de 1995) e adicione um número aleatório de dias com AddDays (obviamente, preste atenção para não ultrapassar a data atual).
Estou um pouco atrasado para o jogo, mas aqui está uma solução que funciona bem:
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;
}
}
}
Método pequeno que retorna uma data aleatória como string, com base em alguns parâmetros de entrada simples. Construído com base nas variações das respostas acima:
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);
}