Search code examples
phparraystimesum

Sum hours of an array of time expressions and format total a H:i:s


I am trying to sum hours with the MySQL format of 00:00:00. I am trying to sum them with a foreach(), but when the sum gets to 24:00:00 it restarts at 00:00:00. I need the total to be potentially greater than 24 hours.

This is my code to sum them:

foreach ($hours as $h) {
    $sumaHoras = date(
        'H:i:s',
        strtotime($sumaHoras) + strtotime($h->horas) - strtotime('00:00')
    );
}

Solution

  • The problem is that with only returning the hour parts of date(), you are removing anything bigger than a full day, so it will only ever return something between 00:00 and 23:59. You should use something other than date() and only when all the seconds are added up.

    So instead you should try something like this:

    function sec2hours($seconds){
      $units = array(
        'hours'   => 3600,
        'minutes' => 60,
        'seconds' => 1,
      );
      foreach($units as &$unit){
        $quot  = intval($seconds / $unit);
        $seconds -= $quot * $unit;
        $unit  = $quot;
      }
      $str = array();
      foreach($units as $name => $value){
        $str[] = ($value === 0?'00':$value);
      }
      return implode(':',$str);
    }
    
    $sum = 0;
    foreach($hours as $h){
     $sum += strtotime($h->horas) - strtotime('00:00');
    }
    $sumaHoras = sec2hours($sum);
    

    The second problem is that strtotime() returns false on hours that should have rolled over into days like 25:00, so if you get one input like that, it will become 0 - strtotime('00:00') and you end up with a huge negative sum. But if all the inputs are between 00-23:00-59 it should be alright.