Я хочу добавить два интервала дат для вычисления общей продолжительности в часах и минутах на самом деле, я хочу выполнить добавление, как показано ниже:
$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;
Любая идея, как выполнить этот тип добавления интервалов, чтобы получить сумму двух интервалов в общем формате часов и минут в PHP
PHP не имеет перегрузки оператора *, поэтому +
с объектами делает PHP попыткой сначала преобразовать их в строку, но DateInterval
не поддерживает это:
interval 1: 03:05 interval 2: 05:00 Total interval : 08:05
Вместо этого вам нужно создать новый объект DateTime
, а затем использовать функцию add для добавления интервалов и, наконец, отобразить разницу в контрольной точке:
$e = new DateTime('00:00'); $f = clone $e; $e->add($interval1); $e->add($interval2); echo "Total interval : ", $f->diff($e)->format("%H:%I"), "\n";
Полный 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";
Вы также можете подумать о том, как DateInterval
сохраняет свои «значения» и затем расширяется от него, чтобы выполнить собственный расчет. Следующий пример ( Demo ) является грубым, он не учитывает перевернутую вещь , он не (re) устанавливает $days
в false
и я не проверял / не тестировал спецификацию ISO спецификатора периода при создании, но я думаю, что это достаточно, чтобы показать идею:
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";
* Если вы пишете PHP-расширение, это действительно возможно (по крайней мере, вроде).
Эта функция позволяет комбинировать любое количество 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>";