web-dev-qa-db-fra.com

Comment générer des dates aléatoires entre deux dates en utilisant php?

Je code une application où je dois attribuer une date aléatoire entre deux horodatages fixes

comment je peux atteindre cet objectif en utilisant php, j'ai cherché d'abord, mais seulement trouvé la réponse pour Java pas php

par exemple :

$string = randomdate(1262055681,1262055681);
50
M.E

PHP a la fonction Rand () :

$int= Rand(1262055681,1262055681);

Il a aussi mt_Rand () , qui est généralement censé avoir un meilleur caractère aléatoire dans les résultats:

$int= mt_Rand(1262055681,1262055681);

Pour transformer un horodatage en chaîne, vous pouvez utiliser date () , c'est-à-dire:

$string = date("Y-m-d H:i:s",$int);
86
zombat

Si les dates sont au format date/heure, utilisez ce moyen le plus simple pour convertir les deux nombres en horodatages, puis définissez-les comme limites minimales et maximales sur un générateur de nombres aléatoires.

Un exemple PHP rapide 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 utilise strtotime () comme suggéré par zombat pour convertir une description datetime en un horodatage Unix, et date () pour définir une date valide à partir de l'horodatage aléatoire généré.

37
Somnath Muluk

Vous pouvez simplement utiliser un nombre aléatoire pour déterminer une date aléatoire. Obtenez un nombre aléatoire entre 0 et le nombre de jours entre les dates. Ensuite, ajoutez simplement ce nombre à la première date.

Par exemple, pour obtenir une date, un nombre aléatoire de jours entre maintenant et 30 jours.

echo date('Y-m-d', strtotime( '+'.mt_Rand(0,30).' days'));
25
Brent Baisley

Une autre solution utilisant PHP DateTime

$start et $end sont DateTime objects et nous les convertissons en horodatage. Ensuite, nous utilisons mt_Rand pour obtenir un horodatage aléatoire entre eux. Enfin, nous recréons un DateTime object.

function randomDateInRange(DateTime $start, DateTime $end) {
    $randomTimestamp = mt_Rand($start->getTimestamp(), $end->getTimestamp());
    $randomDate = new DateTime();
    $randomDate->setTimestamp($randomTimestamp);
    return $randomDate;
}
12
Sam

Voici un autre exemple:

$datestart = strtotime('2009-12-10');//you can change it to your timestamp;
$dateend = strtotime('2009-12-31');//you can change it to your timestamp;

$daystep = 86400;

$datebetween = abs(($dateend - $datestart) / $daystep);

$randomday = Rand(0, $datebetween);

echo "\$randomday: $randomday\n";

echo date("Y-m-d", $datestart + ($randomday * $daystep)) . "\n";
8
ariefbayu

La meilleure façon :

$timestamp = Rand( strtotime("Jan 01 2015"), strtotime("Nov 01 2016") );
$random_Date = date("d.m.Y", $timestamp );
5
Максим С

En utilisant carbon et php Rand entre deux dates

$startDate = Carbon::now();
$endDate   = Carbon::now()->subDays(7);

$randomDate = Carbon::createFromTimestamp(Rand($endDate->timestamp, $startDate->timestamp))->format('Y-m-d');

OR

$randomDate = Carbon::now()->subDays(Rand(0, 7))->format('Y-m-d');
3
vijaykumar

La quantité de strtotime ici est WAY trop élevée.
Pour ceux dont les intérêts vont avant 1971 et après 2038, voici une solution moderne et flexible:

function random_date_in_range( $date1, $date2 ){
    if (!is_a($date1, 'DateTime')) {
        $date1 = new DateTime( (ctype_digit((string)$date1) ? '@' : '') . $date1);
        $date2 = new DateTime( (ctype_digit((string)$date2) ? '@' : '') . $date2);
    }
    $random_u = random_int($date1->format('U'), $date2->format('U'));
    $random_date = new DateTime();
    $random_date->setTimestamp($random_u);
    return $random_date->format('Y-m-d') .'<br>';
}

Appelez ça n'importe quel nombre de façons ...

// timestamps
echo random_date_in_range(157766400,1489686923);

// any date string
echo random_date_in_range('1492-01-01','2050-01-01');

// English textual parsing
echo random_date_in_range('last Sunday','now');

// DateTime object
$date1 = new DateTime('1000 years ago');
$date2 = new DateTime('now + 10 months');
echo random_date_in_range($date1, $date2);

En l'état, la fonction nécessite date1 <= date2.

2
neokio

j'ai eu une même situation avant et aucune des réponses ci-dessus ne résout mon problème, donc je

Entré avec une nouvelle fonction

function randomDate($startDate, $endDate, $count = 1 ,$dateFormat = 'Y-m-d H:i:s')
{
   //inspired by
    // https://Gist.github.com/samcrosoft/6550473

    // Convert the supplied date to timestamp
    $minDateString = strtotime($startDate);
    $maxDateString = strtotime($endDate);

    if ($minDateString > $maxDateString) 
    {
        throw new Exception("From Date must be lesser than to date", 1);

    }

    for ($ctrlVarb = 1; $ctrlVarb <= $count; $ctrlVarb++) 
    { 
       $randomDate[] = mt_Rand($minDateString, $maxDateString); 
    }
    if (sizeof($randomDate) == 1) 
    {
        $randomDate = date($dateFormat, $randomDate[0]);
        return $randomDate;
    }elseif (sizeof($randomDate) > 1) 
    {
        foreach ($randomDate as $randomDateKey => $randomDateValue) 
        {
           $randomDatearray[] =  date($dateFormat, $randomDateValue);
        }
        //return $randomDatearray;
        return array_values(array_unique($randomDatearray));
    }
}

Maintenant la partie test (les données peuvent changer pendant le test)

$fromDate = '2012-04-02';
$toDate = '2018-07-02';

print_r (randomDate ($ fromDate, $ toDate, 1));

le résultat sera

2016-01-25 11:43:22

print_r (randomDate ($ fromDate, $ toDate, 1));

array:10 [▼
  0 => "2015-08-24 18:38:26"
  1 => "2018-01-13 21:12:59"
  2 => "2018-06-22 00:18:40"
  3 => "2016-09-14 02:38:04"
  4 => "2016-03-29 17:51:30"
  5 => "2018-03-30 07:28:48"
  6 => "2018-06-13 17:57:47"
  7 => "2017-09-24 16:00:40"
  8 => "2016-12-29 17:32:33"
  9 => "2013-09-05 02:56:14"
]

Mais après les quelques tests, je pensais à ce qui se passerait si les entrées étaient comme

$fromDate ='2018-07-02 09:20:39';
$toDate = '2018-07-02 10:20:39';

Donc, les doublons peuvent se produire lors de la génération du grand nombre de dates telles que 10,000

donc j'ai ajouté array_unique et cela ne renverra que les non-doublons

1
Manojkiran.A

Le plus simple de tous, cette petite fonction fonctionne pour moi Je l'ai écrite dans une classe d'assistance datetime en tant que méthode statique

/**
 * Return date between two dates
 *
 * @param String $startDate
 * @param String $endDate
 * @return String
 *
 * @author Kuldeep Dangi <[email protected]>
 */
public static function getRandomDateTime($startDate, $endDate)
{
    $randomTime = mt_Rand(strtotime($startDate), strtotime($endDate));
    return date(self::DATETIME_FORMAT_MYSQL, $randomTime);

}
0
Kuldeep Dangi

Une autre solution où nous pouvons utiliser date_format:

 /**
 * Method to generate random date between two dates
 * @param $sStartDate
 * @param $sEndDate
 * @param string $sFormat
 * @return bool|string
 */

function randomDate($sStartDate, $sEndDate, $sFormat = 'Y-m-d H:i:s') {
    // Convert the supplied date to timestamp
    $fMin = strtotime($sStartDate);
    $fMax = strtotime($sEndDate);
    // Generate a random number from the start and end dates
    $fVal = mt_Rand($fMin, $fMax);
    // Convert back to the specified date format
    return date($sFormat, $fVal);
}

Source: https://Gist.github.com/samcrosoft/6550473

Vous pouvez utiliser par exemple:

$date_random = randomDate('2018-07-09 00:00:00','2018-08-27 00:00:00');
0
Sébastien Gicquel