Как мы можем добавить два интервала дат в PHP
Я хочу добавить два интервала дат для вычисления общей продолжительности в часах и минутах на самом деле я хочу выполнить добавление, как показано ниже:
$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
3 ответов
PHP не имеет перегрузки оператора* so +
с объектами делает 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/(демо):
$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
сохраняет свои значения, а затем расширяется от него, чтобы сделать расчет самостоятельно. Следующий пример (демо) грубо, не учитывает перевернутый штука, это значит не (re)set $days
to 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>";