web-dev-qa-db-fra.com

Date aléatoire en C #

Je cherche un code C # moderne et succinct pour générer une date aléatoire entre le 1er janvier 1995 et la date actuelle.

Je pense qu'une solution utilisant Enumerable.Range pourrait rendre ceci plus succinct.

122
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));
}

Pour obtenir de meilleures performances si cela doit être appelé à plusieurs reprises, créez les variables start et gen (et peut-être même range) en dehors de de la fonction.

205
Joel Coehoorn

Cela répond légèrement au commentaire de Joel à propos de la création d’une version légèrement plus optimisée. Au lieu de renvoyer directement une date aléatoire, pourquoi ne pas renvoyer une fonction de générateur qui peut être appelée à plusieurs reprises pour créer une date aléatoire. 

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));
}
21
JaredPar

J'ai pris la réponse de @Joel Coehoorn et apporté les modifications qu'il a conseillées - mettez la variable hors de la méthode et mettez tout en classe. De plus, le temps est aléatoire aussi. Voici le résultat.

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));
    }
}

Et par exemple, comment utiliser pour écrire 100 DateTimes aléatoires sur la console:

RandomDateTime date = new RandomDateTime();
for (int i = 0; i < 100; i++)
{
    Console.WriteLine(date.Next());
}
6
prespic

Eh bien, si vous présentez une optimisation alternative, nous pouvons également choisir un itérateur:

 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));        
}

vous pourriez l'utiliser comme ceci:

int i=0;
foreach(DateTime dt in RandomDay())
{
    Console.WriteLine(dt);
    if (++i == 10)
        break;
}
5
James Curran

Commencez avec un objet à date fixe (1er janvier 1995) et ajoutez un nombre aléatoire de jours avec AddDays (évidemment, faites attention de ne pas dépasser la date actuelle).

3
Gabriele D'Antona

Je suis un peu en retard dans le jeu, mais voici une solution qui fonctionne bien:

    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;
            }
        }
    }
0
Hamit Gündogdu