Converta a duração do vídeo do youtube Api v3 na php

Como faço para converter PT2H34M25S para 2:34:25

Eu procurei e usei esse código. Eu sou novo para regex alguém pode explicar isso? e me ajude com o meu problema

function covtime($youtube_time){ preg_match_all('/(\d+)/',$youtube_time,$parts); $hours = floor($parts[0][0]/60); $minutes = $parts[0][0]%60; $seconds = $parts[0][1]; if($hours != 0) return $hours.':'.$minutes.':'.$seconds; else return $minutes.':'.$seconds; } 

mas este código só me dá HH: MM

tão burro que encontrou a solução:

  function covtime($youtube_time){ preg_match_all('/(\d+)/',$youtube_time,$parts); $hours = $parts[0][0]; $minutes = $parts[0][1]; $seconds = $parts[0][2]; if($seconds != 0) return $hours.':'.$minutes.':'.$seconds; else return $hours.':'.$minutes; } 

Você deve dar uma olhada na sua variável de $parts depois que ela for criada.

 var_dump($parts); 

Compare essa saída com a forma como você está definindo suas variables. Deveria se destacar, obviamente, depois disso.

Acho que a minha próxima pergunta depois disso é que as variações da cadeia de tempo de input esperam e qual a validação que você estará fazendo? As variações do formato de input que você deseja manipular afetarão a complexidade do código real escrito.

Editar: Aqui está uma function atualizada para lidar com os valores numéricos perdidos (se as horas ou minutos forem omitidos) e segundos / horas acima de 60 (não é certo se isso acontecerá). Isso não valida o label dos números:

  • 1 número: suponha que seja segundos
  • 2 números: suponha que seja minutos, segundos
  • 3 ou mais números: assumir que os primeiros 3 números são horas, minutos e segundos (ignorando outros números)

Mais validação pode ser adicionada para analisar a validação da string de input.

  

Usando a class DateTime

Você poderia usar a class DateTime do PHP para conseguir isso. Esta solução é muito mais simples e funcionará mesmo se o formato das quantidades na cadeia estiver em ordem diferente. Uma solução regex (provavelmente) será quebrada em tais casos.

Em PHP, PT2H34M25S é uma cadeia de período de data válida e é entendida pelo analisador DateTime. Em seguida, fazemos uso desse fato, e apenas adicione-o à época Unix usando o método add() . Então você pode formatar a data resultante para obter os resultados necessários:

 function covtime($youtube_time){ $start = new DateTime('@0'); // Unix epoch $start->add(new DateInterval($youtube_time)); return $start->format('H:i:s'); } echo covtime('PT2H34M25S'); 

Demo

As soluções de Amal e Pferate são excelentes! No entanto, a solução Amal continua me dando 1 hora extra. Abaixo está a minha solução, que é o mesmo com Amal, mas a abordagem da diferença e isso funciona para mim.

 $date = new DateTime('1970-01-01'); $date->add(new DateInterval('PT2H34M25S')); echo $date->format('H:i:s') 

datetime->add() referência datetime->add()

Aqui está a minha solução que lida com H, M ou S faltando (teste um vídeo com um comprimento relatado de 1:00:01 e você verá o problema com outras respostas). Os segundos sozinhos são apresentados como 0:01, mas se você quiser mudar, basta alterar o último outro para elseif($M>0) e adicionar outro para segundos, por exemplo, else { return ":$S" }

 // convert youtube v3 api duration eg PT1M3S to HH:MM:SS // updated to handle videos days long eg P1DT1M3S function covtime($yt){ $yt=str_replace(['P','T'],'',$yt); foreach(['D','H','M','S'] as $a){ $pos=strpos($yt,$a); if($pos!==false) ${$a}=substr($yt,0,$pos); else { ${$a}=0; continue; } $yt=substr($yt,$pos+1); } if($D>0){ $M=str_pad($M,2,'0',STR_PAD_LEFT); $S=str_pad($S,2,'0',STR_PAD_LEFT); return ($H+(24*$D)).":$M:$S"; // add days to hours } elseif($H>0){ $M=str_pad($M,2,'0',STR_PAD_LEFT); $S=str_pad($S,2,'0',STR_PAD_LEFT); return "$H:$M:$S"; } else { $S=str_pad($S,2,'0',STR_PAD_LEFT); return "$M:$S"; } } 

Esta é a minha solução, teste concluído!

 preg_match_all("/PT(\d+H)?(\d+M)?(\d+S)?/", $duration, $matches); $hours = strlen($matches[1][0]) == 0 ? 0 : substr($matches[1][0], 0, strlen($matches[1][0]) - 1); $minutes = strlen($matches[2][0]) == 0 ? 0 : substr($matches[2][0], 0, strlen($matches[2][0]) - 1); $seconds = strlen($matches[3][0]) == 0 ? 0 : substr($matches[3][0], 0, strlen($matches[3][0]) - 1); return 3600 * $hours + 60 * $minutes + $seconds; 

Aqui está o código completo para obter, converter e exibir a duração do vídeo

 $vidkey = " " ; // for example: cHPMH26sw2f $apikey = "xxxxxxxxxxxx" ; $dur = file_get_contents("https://www.googleapis.com/youtube/v3/videos?part=contentDetails&id=$vidkey&key=$apikey"); $VidDuration =json_decode($dur, true); foreach ($VidDuration['items'] as $vidTime) { $VidDuration= $vidTime['contentDetails']['duration']; } // convert duration from ISO to M:S $date = new DateTime('2000-01-01'); $date->add(new DateInterval($VidDuration)); echo $date->format('i:s') ; 

Substitua xxxxxxx pela sua API Resultados da chave: 13:07

Por que a complicação. Pense fora da checkbox.

  $seconds = substr(stristr($length, 'S', true), -2, 2); $seconds = preg_replace("/[^0-9]/", '', $seconds); $minutes = substr(stristr($length, 'M', true), -2, 2); $minutes = preg_replace("/[^0-9]/", '', $minutes); $hours = substr(stristr($length, 'H', true), -2, 2); $hours = preg_replace("/[^0-9]/", '', $hours); 

ESTÁ BEM. preg_replace não é realmente necessário, mas eu coloco para garantir apenas números.

Então, para a minha formatação (que você pode fazer como quiser sem limites),

  if($hours == 0){ $h= ''; }else{ $h= $hours.':'; } if($minutes <10){ $m= '0'.$minutes.':'; if($h == ''){ $m= $minutes.':'; } if ($minutes == 0){ $m= $minutes; } }else{ $m= $minutes.':'; } if($seconds <10){ $s= '0'.$seconds; }else{ $s= $seconds; } $time= $h . $m . $s.'s'; 

Experimente a seguinte function:

 function covtime($youtube_time) { $hours = '0'; $minutes = '0'; $seconds = '0'; $hIndex = strpos($youtube_time, 'H'); $mIndex = strpos($youtube_time, 'M'); $sIndex = strpos($youtube_time, 'S'); $length = strlen($youtube_time); if($hIndex > 0) { $hours = substr($youtube_time, 2, ($hIndex - 2)); } if($mIndex > 0) { if($hIndex > 0) { $minutes = substr($youtube_time, ($hIndex + 1), ($mIndex - ($hIndex + 1))); } else { $minutes = substr($youtube_time, 2, ($mIndex - 2)); } } if($sIndex > 0) { if($mIndex > 0) { $seconds = substr($youtube_time, ($mIndex + 1), ($sIndex - ($mIndex + 1))); } else if($hIndex > 0) { $seconds = substr($youtube_time, ($hIndex + 1), ($sIndex - ($hIndex + 1))); } else { $seconds = substr($youtube_time, 2, ($sIndex - 2)); } } return $hours.":".$minutes.":".$seconds; } 

Você pode tentar isso –

 function covtime($youtube_time){ $start = new DateTime('@0'); // Unix epoch $start->add(new DateInterval($youtube_time)); if (strlen($youtube_time)>8) { return $start->format('g:i:s'); } else { return $start->format('i:s'); } } 

DateTime e DateInterval não funcionam no Yii ou em alguma versão do php. Então, esta é a minha solução. Está trabalhando comigo.

 function convertTime($time){ if ($time > 0){ $time_result = ''; $hours = intval($time / 3600); if ($hours > 0) $time_result = $time_result.$hours.':'; $time = $time % 3600; $minutes = intval($time / 60); $seconds = $time % 60; $time_result = $time_result.(($minutes > 9)?$minutes:'0'.$minutes).':'; $time_result = $time_result.(($seconds > 9)?$seconds:'0'.$seconds); }else $time_result = '0:00'; return $time_result; }