je veux ajouter deux intervalles de date pour calculer la durée totale en heures et minutes. En fait, je veux effectuer l'addition comme indiqué ci-dessous:
$a = new DateTime('14:25');
$b = new DateTime('17:30');
$interval1 = $a->diff($b);
echo "interval 1 : " . $interval1->format("%H:%I");
echo "<br />";
$c = new DateTime('08:00');
$d = new DateTime('13:00');
$interval2 = $c->diff($d);
echo "interval 2 : " . $interval2->format("%H:%I");
echo "<br />";
echo "Total interval : " . $interval1 + $interval2;
Toute idée sur la manière d’effectuer ce type d’ajout d’intervalles pour obtenir la somme des deux intervalles en format total heures et minutes en PHP
PHP n'a pas d'opérateur surchargé * donc +
avec des objets permet à PHP d'essayer de les convertir en chaîne, mais DateInterval
ne supporte pas cela:
interval 1: 03:05
interval 2: 05:00
Total interval : 08:05
Au lieu de cela, vous devez créer un nouvel objet DateTime
, puis utiliser la fonction add
pour ajouter les intervalles et afficher la différence au point de référence:
$e = new DateTime('00:00');
$f = clone $e;
$e->add($interval1);
$e->add($interval2);
echo "Total interval : ", $f->diff($e)->format("%H:%I"), "\n";
Full Exmaple/( Demo ):
$a = new DateTime('14:25');
$b = new DateTime('17:30');
$interval1 = $a->diff($b);
echo "interval 1: ", $interval1->format("%H:%I"), "\n";
$c = new DateTime('08:00');
$d = new DateTime('13:00');
$interval2 = $c->diff($d);
echo "interval 2: ", $interval2->format("%H:%I"), "\n";
$e = new DateTime('00:00');
$f = clone $e;
$e->add($interval1);
$e->add($interval2);
echo "Total interval : ", $f->diff($e)->format("%H:%I"), "\n";
Vous voudrez peut-être aussi regarder comment DateInterval
stocke ses valeurs et ensuite en faire le calcul vous-même. L'exemple suivant ( Demo ) est grossier, il ne prend pas en compte le truc inversé , il ne ne (re) règle pas $days
à false
et je n'ai pas vérifié/testé l'ISO. spécification de le spécificateur de période sur la création mais je pense qu’il suffit de montrer l’idée:
class MyDateInterval extends DateInterval
{
/**
* @return MyDateInterval
*/
public static function fromDateInterval(DateInterval $from)
{
return new MyDateInterval($from->format('P%yY%dDT%hH%iM%sS'));
}
public function add(DateInterval $interval)
{
foreach (str_split('ymdhis') as $prop)
{
$this->$prop += $interval->$prop;
}
}
}
$a = new DateTime('14:25');
$b = new DateTime('17:30');
$interval1 = $a->diff($b);
echo "interval 1: ", $interval1->format("%H:%I"), "\n";
$c = new DateTime('08:00');
$d = new DateTime('13:00');
$interval2 = $c->diff($d);
echo "interval 2: ", $interval2->format("%H:%I"), "\n";
$e = MyDateInterval::fromDateInterval($interval1);
$e->add($interval2);
echo "Total interval: ", $e->format("%H:%I"), "\n";
* Si vous écrivez une extension PHP, c'est en fait possible (au moins en quelque sorte).
Cette fonction vous permet de combiner n’importe quel nombre de DateIntervals.
/**
* Combine a number of DateIntervals into 1
* @param DateInterval $...
* @return DateInterval
*/
function addDateIntervals()
{
$reference = new DateTimeImmutable;
$endTime = clone $reference;
foreach (func_get_args() as $dateInterval) {
$endTime = $endTime->add($dateInterval);
}
return $reference->diff($endTime);
}
function compare_dateInterval($interval1, $operator ,$interval2){
$interval1_str = $interval1->format("%Y%M%D%H%I%S");
$interval2_str = $interval2->format("%Y%M%D%H%I%S");
switch($operator){
case "<":
return $interval1 < $interval2;
case ">":
return $interval1 > $interval2;
case "==" :
return $interval1 == $interval2;
default:
return NULL;
}
}
function add_dateInterval($interval1, $interval2){
//variables
$new_value= [];
$carry_val = array(
's'=>['value'=>60,'carry_to'=>'i'],
'i'=>['value'=>60,'carry_to'=>'h'],
'h'=>['value'=>24,'carry_to'=>'d'],
'm'=>['value'=>12,'carry_to'=>'y']
);
//operator selection
$operator = ($interval1->invert == $interval2->invert) ? '+' : '-';
//Set Invert
if($operator == '-'){
$new_value['invert'] = compare_dateInterval($interval1,">",$interval2)?$interval1->invert:$interval2->invert;
}else{
$new_value['invert'] = $interval1->invert;
}
//Evaluate
foreach( str_split("ymdhis") as $property){
$expression = 'return '.$interval1->$property.' '.$operator.' '.$interval2->$property.';';
$new_value[$property] = eval($expression);
$new_value[$property] = ($new_value[$property] > 0) ? $new_value[$property] : -$new_value[$property];
}
//carry up
foreach($carry_val as $property => $option){
if($new_value[$property] >= $option['value']){
//Modulus
$new_value[$property] = $new_value[$property] % $option['value'];
//carry over
$new_value[$option['carry_to']]++;
}
}
$nv = $new_value;
$result = new DateInterval("P$nv[y]Y$nv[m]M$nv[d]DT$nv[h]H$nv[i]M$nv[s]S");
$result->invert = $new_value['invert'];
return $result;
}
$a = new DateTime('00:0');
$b = new DateTime('17:30');
$interval1 = $a->diff($b);
echo "interval 1: ", $interval1->format("%H:%I"), "<br>";
$c = new DateTime('08:01:00');
$d = new DateTime('13:30:33');
$interval2 = $c->diff($d);
echo "interval 2: ", $interval2->format("%H:%I"), "<br>";
$addition = add_dateInterval($interval1,$interval2);
echo "<pre>";
echo var_dump($addition);
echo "</pre>";