insertar hora formulario fechas fecha español comparar calendario actual php datetime addition dateinterval

hora - Cómo podemos agregar dos intervalos de fechas en PHP



insertar calendario en formulario html (3)

Quiero agregar dos intervalos de fechas para calcular la duración total en horas y minutos. De hecho, deseo realizar una adición como se muestra a continuación:

$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;

Cualquier idea sobre cómo realizar este tipo de adición de intervalo para obtener la suma de los dos intervalos en formato de horas y minutos totales en PHP


Esta función le permite combinar cualquier cantidad 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); }


PHP no tiene sobrecarga de operador * así que + con objetos hace que PHP intente convertirlos a cadena primero, pero DateInterval no admite eso:

interval 1: 03:05 interval 2: 05:00 Total interval : 08:05

En su lugar, debe crear un nuevo objeto DateTime , luego usar la función de agregar para agregar los intervalos y finalmente mostrar la diferencia al punto de referencia:

$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";

También puede considerar buscar cómo DateInterval almacena sus ''valores y luego extenderlos para hacer su propio cálculo. El siguiente ejemplo ( Demo ) es áspero, no tiene en cuenta la cosa invertida , no (re) establece $days en false y no he verificado / probado la especificación ISO del especificador de período en la creación, pero creo que es suficiente para mostrar la idea:

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 escribe una extensión PHP, en realidad es posible (al menos tipo de).


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>";