J'essaie de boucler des dates avec PHP. Actuellement, mon code est bloqué dans une boucle répétée 110307. J'ai besoin du format de date à YymMDD. Voici ce que j'essayais d'utiliser:
4 Réponses :
Voici une partie d'un code que j'utilise peut probablement être amélioré, dépend de la version PHP que vous utilisez.
//usage
$Iterator=class Dates_DateIterator::factory('Daily',
new Datetime('20100227'),
new Datetime('20100324'));
foreach($Iterator as $i=>$day){
var_dump($i);
var_dump($day);
}
//code lib
abstract class Dates_DateIterator implements Iterator
{
/**
* Factory method, saves some code, also enable me to put everything in the same class
* as we use Autoload to load classes.
*/
static public function factory($cycle,DateTime $DateI,DateTime $DateII){
switch($cycle){
case 'Daily':
return new DaysIterator($DateI,$DateII);
case 'Weekly':
return new WeeksIterator($DateI,$DateII);
case 'Monthly':
return new MonthsIterator($DateI,$DateII);
case 'Yearly':
return new YearsIterator($DateI,$DateII);
default:
throw(new Exception('No valid cycle was chosen to iterate over'));
}
}
/**
* @var DateTime represents the start range.
*/
public $FromDate;
/**
* @var DateTime represents the end range.
*/
public $ToDate;
/**
* @var DateTime Current Date.
*/
protected $CurrentDate;
public function __construct(DateTime $DateI,DateTime $DateII)
{
if($DateII->format('U') > $DateI->format('U'))
{
$this->FromDate=$DateI;
$this->ToDate=$DateII;
$this->CurrentDate=$DateI;
}
else
{
$this->FromDate=$DateII;
$this->ToDate=$DateI;
$this->CurrentDate=$DateII;
}
}//EOF constructor
/**
* @return DateTime
*/
public function getClonedCurrent(){
return clone($this->CurrentDate);
}
public function current()
{
return $this->CurrentDate;
}//EOF current
public function currentDate()
{
return $this->CurrentDate->format('Ymd');
}//EOF current
public function rewind()
{
$this->CurrentDate=$this->FromDate;
}//EOF rewind
public function valid()
{
//Kill hours/minutes/seconds. If we are to add hours and minutes iterators, we will need to rethink this.
return (floor($this->CurrentDate->format('U')/(3600*24)) <= floor($this->ToDate->format('U')/(3600*24)));
}//EOF valid
}//EOF CLASS DateIterator
class DaysIterator extends SiTEL_Dates_DateIterator
{
public function __construct(DateTime $DateI,DateTime $DateII)
{
parent::__construct($DateI,$DateII);
}//EOF constructor
public function next()
{
$this->CurrentDate->modify('+1 day');
}//EOF next
public function key()
{
return $this->CurrentDate->format('d');
}//EOF key
}//EOD CLASS DaysIterator
Wow, c'est un poids lourd superbe.
@Paul Schreiber a lu la chose entière, elle fait partie d'un cadre plus grand / lib. C'est lourd, vous avez raison, car je dois utiliser le même code exactement pour différents cycles (il fait partie d'une calculatrice de répéteur d'événement). Mais ... cela m'a pris moins de temps pour le mettre ici que le moment où il vous a fallu pour l'écrire :-)
Je peux voir ça. Il semble qu'il y ait une grosse perf enflammée pour importer un cadre et allouer / instantiier / détruire n objets.
Essayez d'utiliser un horodatage UNIX et d'ajouter 86400 à chaque fois. Ça doit être plus rapide que l'appelant strtotime () code>. Vous pouvez Conversions horodaques de recherche en ligne . <?php
$check_date = 1267228800; // '2010-02-27';
$end_date = 1269388800; // '2010-03-24';
while($check_date != $end_date){
$check_date += 86400;
echo date("Ymd", $check_date) . '<br>';
}
?>
Le format de date doit être laissé comme Yymmdd ou au moins, il commencera à être utilisé et doit être utilisé dans mon code.
Vous pouvez faire une conversion rapide à l'extérieur de la boucle, ce qui est mille moins chère (O (1)) que de le faire chaque itération (O (n)).
N'utilisez jamais 86400 secondes pendant une journée en raison de la lumière du jour lorsque la journée a 23 ou 25 heures!
Un truc soigné pour les dates d'itération consiste à profiter de la capacité de MKTime à normaliser les dates , quelque chose comme ceci: p> strtotime code> interprète "100227" comme 10:02:27 Aujourd'hui, pas 2010-02-27. Donc, après la première étape, $ check_date code> (aujourd'hui) est "110307". À toutes les étapes suivantes, "110307" est à nouveau interprétée comme une fois aujourd'hui, donnant aujourd'hui $ check_date code> comme "110307".
Je n'ai pas vraiment utilisé le code que vous m'avez donné, mais votre raison du problème m'a aidé à trouver une solution. Merci pour votre aide
L'explication était la partie importante.
Voici comment je préfère le faire:
$startDate = new DateTime('20100227');
$endDate = new DateTime('20100324');
while ($startDate <= $endDate) {
// your code here
...
// go to the next day
$startDate->add(new DateInterval('P1D'));
}
Puis au lieu de
Modifier ('+ 1 jour'); code> par exemple, vous pouvez utiliser la méthode-> Ajouter code>.@Itay moav pouvez-vous me donner un exemple de ce que vous entendez par -> Ajouter