2013-01-06 6 views
4

Je suis en train d'écrire un script php (ou ligne de code) pour faire écho un temps aléatoire et la date entre 2 dates, par exempletemps aléatoire et la date entre 2 valeurs de date

2012-12-24 13:03

qui serait entre mes dates du 1er Octobre 2012 et le 1 janvier 2013.

Toutes les idées de la meilleure façon de le faire? Merci d'avance.

+0

C'est facile - vous avez besoin d'un horodatage aléatoire. Puis, à partir de l'horodatage aléatoire, vous pourrez extraire l'heure ... – Yang

+0

Avez-vous essayé quelque chose? –

+1

Voulez-vous inclure le 1er octobre et le 1er janvier dans les dates aléatoires ou seulement entre eux? – Ray

Répondre

21

facile :) Il suffit de choisir 2 dates aléatoires, convertir EPOCH et aléatoire entre ces 2 valeurs :)

EPOCH - Le temps écoulé depuis le 1/1/1970, en quelques secondes.
Vous pouvez utiliser la fonction strtotime() pour que les chaînes de date se transforment en période d'utilisation, et la fonction date() pour que l'opération revienne dans l'autre sens.

function rand_date($min_date, $max_date) { 
    /* Gets 2 dates as string, earlier and later date. 
     Returns date in between them. 
    */ 

    $min_epoch = strtotime($min_date); 
    $max_epoch = strtotime($max_date); 

    $rand_epoch = rand($min_epoch, $max_epoch); 

    return date('Y-m-d H:i:s', $rand_epoch); 
} 
+0

cela devrait être un commentaire.les réponses devraient avoir plus de «viande» –

+0

J'espère que je l'ai fait mieux :) – Infinity

+0

@Infinity C'est la façon dont je l'ai fait à la fin, merci pour toutes les réponses. – Sara44

0

Ok, voici quelque chose

$date_start = strtotime('1 October 2012'); 
$date_end = strtotime('1 January 2013'); 
$rand_date = rand($date_start, $date_end); 
echo(date('d.m.Y H:i', $rand_date)); 
2

En supposant que vous souhaitez inclure 1er Octobre mais pas inclure le 1 janvier ...

$start = strtotime("2012-10-01 00:00:00"); 
$end = strtotime("2012-12-31 23:59:59"); 

$randomDate = date("Y-m-d H:i:s", rand($start, $end)); 

echo $randomDate; 
2

si fou il peut fonctionner tout simplement

function randomDate($start_date, $end_date) 
{ 
//make timetamps 
$min = strtotime($start_date); 
$max = strtotime($end_date); 

//random date 
$rand_date = rand($min, $max); 

//format it 
return date('Y-m-d H:i:s', $rand_date); 
} 
1

Voici un code pour accomplir est:

$randDate=date('Y-m-d', mt_rand(strtotime('2012-10-01'), strtotime('2013-01-01'))); 
4

Vous voulez probablement définir une résolution, par exemple une minute, ou trois minutes ou 15 secondes ou un et une demi-journée ou de ce pas. Le hasard doit être appliqué sur toute la période, j'ai choisi une minute ici pour des fins exemplaires (il y a 132480 minutes dans votre période).

$start = new Datetime('1st October 2012'); 
$end  = new Datetime('1st Jan 2013'); 
$interval = new DateInterval('PT1M'); // Resolution: 1 Minute 
$period = new DatePeriod($start, $interval, $end); 
$random = new RandomIterator($period); 

list($result) = iterator_to_array($random, false) ? : [null];  

Ce par exemple donne:

class DateTime#7 (3) { 
    public $date => 
    string(19) "2012-10-16 02:06:00" 
    public $timezone_type => 
    int(3) 
    public $timezone => 
    string(13) "Europe/Berlin" 
} 

Vous pouvez find the RandomIterator here. Sans elle, il faudra un peu plus (environ 1,5 le nombre d'itérations par rapport à l'exemple ci-dessus) en utilisant:

$count = iterator_count($period); 
$random = rand(1, $count); 

$limited = new LimitIterator(new IteratorIterator($period), $random - 1, 1); 
$limited->rewind(); 
$result = $limited->current(); 

J'ai aussi essayé avec les secondes, mais cela prendrait assez long. Vous voulez probablement d'abord trouver un jour au hasard (92 jours), puis un peu de temps au hasard.

Aussi j'ai couru quelques tests et je ne pouvais trouver aucun avantage à utiliser DatePeriod pour autant que vous êtes sur les résolutions communes comme seconde:

$start = new Datetime('1st October 2012'); 
$end  = new Datetime('1st Jan 2013'); 

$random = new DateTime('@' . mt_rand($start->getTimestamp(), $end->getTimestamp())); 

ou minutes:

/** 
* @param DateTime $start 
* @param DateTime $end 
* @param int|DateInterval $resolution in Seconds or as DateInterval 
* @return DateTime 
*/ 
$randomTime = function (DateTime $start, DateTime $end, $resolution = 1) { 

    if ($resolution instanceof DateInterval) { 
     $interval = $resolution; 
     $resolution = ($interval->m * 2.62974e6 + $interval->d) * 86400 + $interval->h * 60 + $interval->s; 
    } 

    $startValue = floor($start->getTimestamp()/$resolution); 
    $endValue = ceil($end->getTimestamp()/$resolution); 
    $random  = mt_rand($startValue, $endValue) * $resolution; 

    return new DateTime('@' . $random); 
}; 

$random = $randomTime($start, $end, 60); 
+0

+ bon hacking créant votre propre 'seek' sur' Traversable' avec 'IteratorIterator' +' LimitIterator' – Baba

+0

@Baba: Oui, mais cela itére deux fois. Peut-être connaissez-vous un algorithme de kewl pour obtenir une valeur aléatoire à partir d'un ensemble d'éléments inconnus sans connaître la taille de l'ensemble initial? – hakre

+0

ce n'est pas possible sans 'loop' ce qui peut être fait est de limiter la boucle à un en étendant' DatePeriod' pour implémenter 'ArrayIterator' de cette façon que vous élimineriez la boucle en double et utilisez juste' rand' avec 'ArrayIterator :: seek 'pour obtenir la date de rand – Baba

Questions connexes