Sto cercando un codice C # moderno e conciso per generare una data casuale tra il 1 gennaio 1995 e la data corrente.
Sto pensando a una soluzione che utilizza Enumerable.Range in qualche modo può renderlo più conciso.
Sto cercando un codice C # moderno e conciso per generare una data casuale tra il 1 gennaio 1995 e la data corrente.
Sto pensando a una soluzione che utilizza Enumerable.Range in qualche modo può renderlo più conciso.
Risposte:
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));
}
Per prestazioni migliori se questo verrà chiamato ripetutamente, creare le variabili start
e gen
(e forse anche range
) al di fuori della funzione.
Ciò è in leggera risposta al commento di Joel sulla creazione di una versione leggermente più ottimizzata. Invece di restituire direttamente una data casuale, perché non restituire una funzione generatore che può essere chiamata ripetutamente per creare una data casuale.
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();
poi la chiami per ottenere date casuali: var randomDate = getRandomDate();
ricorda che devi riutilizzare getRandomDate affinché questo sia più utile della risposta di Joel.
Ho preso la risposta di @Joel Coehoorn e ho apportato le modifiche da lui suggerite: estrai la variabile dal metodo e metti tutto in classe. Inoltre ora anche il tempo è casuale. Ecco il risultato.
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));
}
}
Ed esempio come usare per scrivere 100 DateTime casuali sulla 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));
.
Bene, se presenterai un'ottimizzazione alternativa, possiamo anche optare per un iteratore:
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));
}
potresti usarlo in questo modo:
int i=0;
foreach(DateTime dt in RandomDay())
{
Console.WriteLine(dt);
if (++i == 10)
break;
}
Inizia con un oggetto data fisso (1 gennaio 1995) e aggiungi un numero casuale di giorni con AddDays (ovviamente, fai attenzione a non superare la data corrente).
Sono un po 'in ritardo nel gioco, ma ecco una soluzione che funziona bene:
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;
}
}
}
Piccolo metodo che restituisce una data casuale come stringa, basata su alcuni semplici parametri di input. Costruito sulla base delle variazioni delle risposte sopra:
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);
}