2012-07-19 28 views
22

tôi muốn thêm hai khoảng thời gian ngày để tính toán tổng thời gian trong giờ và phút trong thực tế, tôi muốn thực hiện addittion như hình dưới đây:Làm sao chúng ta có thể thêm hai khoảng thời gian ngày trong 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; 

Bất kỳ ý tưởng làm thế nào để thực hiện loại bổ sung khoảng thời gian này để lấy tổng của hai khoảng thời gian trong tổng số giờ và định dạng phút trong PHP

Trả lời

33

PHP không có quá tải toán tử * vì vậy làm cho PHP cố gắng chuyển đổi chúng thành chuỗi trước, nhưng DateInterval không hỗ trợ điều đó:

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

Thay vào đó bạn cần phải tạo ra một đối tượng mới DateTime, sau đó sử dụng add chức năng để thêm các khoảng và cuối cùng hiển thị sự khác biệt với các điểm tham chiếu:

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

Bạn cũng có thể muốn xem xét tìm cách DateInterval cửa hàng giá trị của nó và sau đó mở rộng f rom nó để làm việc tính toán của riêng bạn. Ví dụ sau (Demo) là thô, nó không đưa vào tài khoản the inverted thingy, nó not (re)set $days to false và tôi đã không kiểm tra/kiểm tra các đặc điểm kỹ thuật ISO của the period specifier on creation nhưng tôi nghĩ rằng nó là đủ để cho thấy ý tưởng:

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

* Nếu bạn viết một phần mở rộng PHP, nó thực sự là có thể (ít nhất là loại).

+0

Một số thí nghiệm hơn: http://codepad.viper-7.com/Lh2DtL ([ý chính] (https: // ý chính .github.com/3142405)) – hakre

+0

Xin chào, nếu như, với giải pháp của bạn, tổng số lớn hơn 60 giây, 60 phút, 24 giờ, ... vv? :) – Talus

+0

@Talus: Xem ý chính, không phải là nó hoàn hảo, nhưng nó cho thấy cách bạn có thể xử lý điều đó. – hakre

6

Chức năng này cho phép bạn kết hợp bất kỳ số lượng 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); 
} 
+0

Điều này không làm việc cho tôi, '$ endTime' tôi nghĩ vì' DateTimeImmutable'.Làm việc khi tôi thay đổi 'DateTimeImmutable' mới cho' new DateTime() ' – Gyfis

+1

@Gyfis Strange, nó hoạt động tốt cho tôi. Hãy nhớ rằng Immutables sẽ trả về một thể hiện mới khi thay đổi. –

0
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>"; 
Các vấn đề liên quan