privateRandom gen =newRandom();DateTimeRandomDay(){DateTime start =newDateTime(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 starte gen(e talvez até range) fora da função.
Aleatório é apenas pseudo-aleatório. Se você precisar realmente aleatório, tente usar RNGCryptoServiceProvider no espaço para nome System.Security.Cryptography.
Tbf # 02:
Obrigado tvanfosson. Pseudo-aleatório é suficiente para esse problema.
Judah Gabriel Himango
5
Na verdade, o Random não é nem particularmente pseudo-aleatório, a menos que você mantenha a instância por um tempo e continue obtendo valores dela.
David Mitchell
2
É por isso que isso é apenas uma amostra, e não um código de produção.
Joel Coehoorn
1
Sim, isso funciona para mim; meu código do mundo real terá a instância Random fora do próprio método.
Judah Gabriel Himango 01/06/09
25
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 =newDateTime(1995,1,1);Random gen =newRandom();int range =((TimeSpan)(DateTime.Today- start)).Days;return()=> start.AddDays(gen.Next(range));}
Você pode explicar como isso é benéfico? Não foi possível iniciar, geração e intervalo como membros da classe?
Mark A. Nicolosi
Eles poderiam e, neste caso, são. Sob o capô, isso gerará um fechamento lexical que é um clrass que contém início, gen e intervalo como membros. Isso é apenas mais conciso.
JaredPar 12/10/08
Bom função, eu estou apenas esperando que ninguém vai usá-lo como:for (int i = 0; i < 100; i++) { array[i].DateProp = RandomDayFunc()(); }
Aidiakapi
2
Como essa função é usada, alguém pode explicar? Quero dizer, como posso chamá-lo?
Burak Karakuş 01/01
2
@ BurakKarakuş: Você obtém uma fábrica primeiro: 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.
Şafak Gür
8
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.
classRandomDateTime{DateTime start;Random gen;int range;publicRandomDateTime(){
start =newDateTime(1995,1,1);
gen =newRandom();
range =(DateTime.Today- start).Days;}publicDateTimeNext(){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 =newRandomDateTime();for(int i =0; i <100; i++){Console.WriteLine(date.Next());}
Por que você cria Random () duas vezes? Uma vez na classe, declaração de variável gen e outra hora no c-tor?
pixel
Sim, uma vez é o suficiente. Eu consertei isso.
prespic 15/08/17
1
É cerca de quatro vezes mais rápido gerar apenas um número aleatório de segundos e adicioná-lo à sua data de início: range = (int)(DateTime.Today - start).TotalSeconds;e return start.AddSeconds(gen.Next(range));.
Jurgy
5
Bem, se você apresentar otimização alternativa, também podemos optar por um iterador:
staticIEnumerable<DateTime>RandomDay(){DateTime start =newDateTime(1995,1,1);Random gen =newRandom();int range =((TimeSpan)(DateTime.Today- start)).Days;while(true)yieldreturn start.AddDays(gen.Next(range));}
você poderia usá-lo assim:
int i=0;foreach(DateTime dt inRandomDay()){Console.WriteLine(dt);if(++i ==10)break;}
Uma coisa a considerar entre um iterador e uma função de gerador é que a solução do iterador produzirá um valor IDisposable. Isso força o chamador a descartar ou pagar o preço de ter um finalizador ativo no GC. As necessidades de geradores sem descartar
JaredPar
2
@ JaredPar, isso não está certo. Só porque um tipo implementa IDisposable não significa que é finalizável.
Drew Noakes
3
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).
Obrigado Friol. Eu ia perguntar como limitar o número passado aleatoriamente. Joel postou um exemplo com amostra de código, então vou marcar sua resposta como a resposta.
Judah Gabriel Himango
0
Estou um pouco atrasado para o jogo, mas aqui está uma solução que funciona bem:
voidMain(){var dateResult =GetRandomDates(newDateTime(1995,1,1),DateTime.UtcNow,100);foreach(var r in dateResult)Console.WriteLine(r);}publicstaticIList<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;}publicstaticIEnumerable<int>GetRandomNumbers(int size){var data =newbyte[4];
using (var rng =newSystem.Security.Cryptography.RNGCryptoServiceProvider(data)){for(int i =0; i < size; i++){
rng.GetBytes(data);varvalue=BitConverter.ToInt32(data,0);yieldreturnvalue<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:
publicstringRandomDate(int startYear =1960,string outputDateFormat ="yyyy-MM-dd"){DateTime start =newDateTime(startYear,1,1);Random gen =newRandom(Guid.NewGuid().GetHashCode());int range =(DateTime.Today- start).Days;return start.AddDays(gen.Next(range)).ToString(outputDateFormat);}
Respostas:
Para um melhor desempenho, se isso for chamado repetidamente, crie as variáveis
start
egen
(e talvez atérange
) fora da função.fonte
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?
fonte
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.
E exemplo como usar para escrever 100 DateTimes aleatórios no console:
fonte
range = (int)(DateTime.Today - start).TotalSeconds;
ereturn start.AddSeconds(gen.Next(range));
.Bem, se você apresentar otimização alternativa, também podemos optar por um iterador:
você poderia usá-lo assim:
fonte
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).
fonte
Estou um pouco atrasado para o jogo, mas aqui está uma solução que funciona bem:
fonte
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:
fonte