186 votes

Générer une date aléatoire entre deux autres dates

Comment puis-je générer une date aléatoire qui doit se situer entre deux autres dates données ?

La signature de la fonction doit être quelque chose comme ceci :

random_date("1/1/2008 1:30 PM", "1/1/2009 4:50 AM", 0.34)
                   ^                       ^          ^

            date generated has  date generated has  a random number
            to be after this    to be before this

et renverrait une date telle que : 2/4/2008 7:20 PM

0 votes

La façon dont la question est présentée actuellement ne permet pas de savoir si vous souhaitez que la date ou l'heure soit aléatoire. Votre exemple suggère que vous recherchez une heure. Si elle doit se situer entre les deux dates, vous pouvez modifier les réponses données jusqu'à présent pour les adapter à vos besoins et exclure l'heure de début et de fin. Enfin, dans la plupart des réponses, comme celle qui a été acceptée, le code produit une date excluant l'heure de fin en raison de la troncature en int. Pour générer une heure qui peut inclure la fin dans la réponse, changez le code en ptime = stime + prop * (etime - stime) + 0.5

0 votes

Oui, la question portait probablement sur l'interpolation, et tous ceux qui la trouvent veulent une date aléatoire :)

174voto

Tom Alsberg Points 3253

Convertissez les deux chaînes en horodatage (dans la résolution de votre choix, par exemple en millisecondes, en secondes, en heures, en jours, etc.), soustrayez la première de la seconde, multipliez votre nombre aléatoire (en supposant qu'il soit distribué dans l'ordre de grandeur suivant range [0, 1] ) avec cette différence, et ajouter à nouveau à la précédente. Reconvertissez l'horodatage en chaîne de dates et vous obtenez une heure aléatoire dans cette plage.

Exemple Python (la sortie est presque dans le format que vous avez spécifié, à l'exception de 0 padding - blâmez les conventions du format de temps américain) :

import random
import time

def str_time_prop(start, end, time_format, prop):
    """Get a time at a proportion of a range of two formatted times.

    start and end should be strings specifying times formatted in the
    given format (strftime-style), giving an interval [start, end].
    prop specifies how a proportion of the interval to be taken after
    start.  The returned time will be in the specified format.
    """

    stime = time.mktime(time.strptime(start, time_format))
    etime = time.mktime(time.strptime(end, time_format))

    ptime = stime + prop * (etime - stime)

    return time.strftime(time_format, time.localtime(ptime))

def random_date(start, end, prop):
    return str_time_prop(start, end, '%m/%d/%Y %I:%M %p', prop)

print(random_date("1/1/2008 1:30 PM", "1/1/2009 4:50 AM", random.random()))

1 votes

Cette approche ne prend pas en charge les dates qui commencent avant 1970.

0 votes

Cela ne soutient pas les dates avant 1900.

143voto

nosklo Points 75862
from random import randrange
from datetime import timedelta

def random_date(start, end):
    """
    This function will return a random datetime between two datetime 
    objects.
    """
    delta = end - start
    int_delta = (delta.days * 24 * 60 * 60) + delta.seconds
    random_second = randrange(int_delta)
    return start + timedelta(seconds=random_second)

La précision est de quelques secondes. Vous pouvez augmenter la précision jusqu'aux microsecondes, ou la diminuer jusqu'à, disons, la demi-heure, si vous le souhaitez. Pour cela, il suffit de modifier le calcul de la dernière ligne.

exemple d'exécution :

from datetime import datetime

d1 = datetime.strptime('1/1/2008 1:30 PM', '%m/%d/%Y %I:%M %p')
d2 = datetime.strptime('1/1/2009 4:50 AM', '%m/%d/%Y %I:%M %p')

print(random_date(d1, d2))

sortie :

2008-12-04 01:50:17

3 votes

L'utilisation de la start dans ce cas est tout à fait correct. Le seul problème que je vois dans le code est l'utilisation de seconds de l'attribut delta . Cela ne renverrait pas le nombre total de secondes dans l'intervalle entier ; au lieu de cela, c'est juste le nombre de secondes du composant "time" (quelque chose entre 0 et 60) ; un timedelta a un total_seconds qui doit être utilisée à la place.

8 votes

@emyller : Non, j'utilise (delta.days * 24 * 60 * 60) + delta.seconds ce qui donne le nombre total de secondes. Le site total_seconds() est nouvelle dans python 2.7 et n'existait pas en 2009 lorsque j'ai répondu à la question. Si vous avez python 2.7, vous devriez l'utiliser à la place, mais le code fonctionne bien tel quel.

0 votes

Je n'étais pas au courant de l'inexistence de cette méthode en 2.7-. Je viens de vérifier qu'un objet timedelta est fondamentalement composé de nombres de jours et de secondes, donc tu as raison :-)

96voto

Artur Barseghyan Points 439

Réponse actualisée

C'est encore plus simple en utilisant Faker .

Installation

pip install faker

Utilisation :

from faker import Faker
fake = Faker()

fake.date_between(start_date='today', end_date='+30y')
# datetime.date(2025, 3, 12)

fake.date_time_between(start_date='-30y', end_date='now')
# datetime.datetime(2007, 2, 28, 11, 28, 16)

# Or if you need a more specific date boundaries, provide the start 
# and end dates explicitly.
import datetime
start_date = datetime.date(year=2015, month=1, day=1)
fake.date_between(start_date=start_date, end_date='+30y')

Ancienne réponse

C'est très simple en utilisant le radar

Installation

pip install radar

Utilisation

import datetime

import radar 

# Generate random datetime (parsing dates from str values)
radar.random_datetime(start='2000-05-24', stop='2013-05-24T23:59:59')

# Generate random datetime from datetime.datetime values
radar.random_datetime(
    start = datetime.datetime(year=2000, month=5, day=24),
    stop = datetime.datetime(year=2013, month=5, day=24)
)

# Just render some random datetime. If no range is given, start defaults to 
# 1970-01-01 and stop defaults to datetime.datetime.now()
radar.random_datetime()

3 votes

upvote pour avoir suggéré le module faker.. J'utilisais pour générer le profil mais je n'ai pas utilisé l'utilitaire de date faker est un très bon module pendant le test.

0 votes

J'obtiens la sortie dans ce format datetime.date(2039, 3, 16) Mais je veux un résultat comme celui-ci 2039-03-16 . Comment faire ?

0 votes

Vous voulez dire que vous voulez une chaîne de caractères ? Très facile (il suffit de la formater en conséquence) : fake.date_between(start_date='today', end_date='+30y').strftime('%Y-%m-%d') .

95voto

emyller Points 829

Une toute petite version.

import datetime
import random

def random_date(start, end):
    """Generate a random datetime between `start` and `end`"""
    return start + datetime.timedelta(
        # Get a random amount of seconds between `start` and `end`
        seconds=random.randint(0, int((end - start).total_seconds())),
    )

Notez que les deux start et end Les arguments doivent être datetime objets. Si vous avez des chaînes de caractères à la place, il est assez facile de les convertir. Les autres réponses indiquent des moyens de le faire.

1voto

ConroyP Points 24021

La façon la plus simple de procéder est de convertir les deux nombres en horodatages, puis de les définir comme les limites minimales et maximales d'un générateur de nombres aléatoires.

Un exemple rapide en PHP serait :

// Find a randomDate between $start_date and $end_date
function randomDate($start_date, $end_date)
{
    // Convert to timetamps
    $min = strtotime($start_date);
    $max = strtotime($end_date);

    // Generate random number using above bounds
    $val = rand($min, $max);

    // Convert back to desired date format
    return date('Y-m-d H:i:s', $val);
}

Cette fonction fait appel à [strtotime()](http://ie.php.net/strtotime) pour convertir une description de date en un timestamp Unix, et [date()](http://ie.php.net/date) pour obtenir une date valide à partir de l'horodatage aléatoire qui a été généré.

0 votes

Si quelqu'un peut écrire cela en python, ce serait utile.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X