I'm, getting this array from a youtube API request, but the duration format is very rare in my opinion. Why didn't they just throw seconds in there? In any case this is the array
[duration] => PT2M3S
[dimension] => 2d
[definition] => sd
[caption] => false
Is there a way to convert this duration to a "H:i:s" format in PHP?
Thanks in advance for your help
In fact it is simple ISO8601 date. Split string with regexp like (\d+)
to minutes and seconds. Then get integer part of division of minutes by 60 to get hours. Get remainder of that division to get minutes.
here is an example that should work though i didn't tested it
preg_match_all('/(\d+)/',$youtube_time,$parts);
$hours = floor($parts[0][0]/60);
$minutes = $parts[0][0]%60;
$seconds = $parts[0][1];
acidjazz has a great solution, but there is a typo where it displays the minutes. It should be $di->i
for minutes, not $di->m
. You can also remove the "public static" portion if you're not using it in an object, and I took out the sprintf()
.
Otherwise the function works as is:
function duration($ytDuration) {
$di = new DateInterval($ytDuration);
$string = '';
if ($di->h > 0) {
$string .= $di->h.':';
}
return $string.$di->i.':'.$di->s;
}
I would have added this as a comment to his answer, but there's the whole "You need 50 reputation to comment" BS that prevents me from sticking to the flow of this thread.
You can use php's DateInterval Class to parse it properly. For example a function in a youtube wrapper class to parse it to the format YouTube displays might look like:
public static function duration($ytDuration) {
$di = new DateInterval($ytDuration);
$string = '';
if ($di->h > 0) {
$string .= $di->h.':';
}
return $string.$di->m.':'.sprintf('%02s',$di->s);
}
I used @chris-z-s 's answer here , and converted it to php :
function getDurationSeconds($duration){
preg_match_all('/[0-9]+[HMS]/',$duration,$matches);
$duration=0;
foreach($matches as $match){
//echo '<br> ========= <br>';
//print_r($match);
foreach($match as $portion){
$unite=substr($portion,strlen($portion)-1);
switch($unite){
case 'H':{
$duration += substr($portion,0,strlen($portion)-1)*60*60;
}break;
case 'M':{
$duration +=substr($portion,0,strlen($portion)-1)*60;
}break;
case 'S':{
$duration += substr($portion,0,strlen($portion)-1);
}break;
}
}
// echo '<br> duratrion : '.$duration;
//echo '<br> ========= <br>';
}
return $duration;
}
it worked with me :)
this is my solution:
preg_match('/(\d+)H/', $duration, $match);
$h = ($match[0])?filter_var($match[0], FILTER_SANITIZE_NUMBER_INT).":":'';
preg_match('/(\d+)M/', $duration, $match);
$m = filter_var($match[0], FILTER_SANITIZE_NUMBER_INT).":";
preg_match('/(\d+)S/', $youtube_date, $match);
$s = filter_var($match[0], FILTER_SANITIZE_NUMBER_INT);
echo: "Duration: " . $h.$m.$s;
##:##:## Time format on PHP
function NormalizeDuration($duration){
preg_match('#PT(.*?)H(.*?)M(.*?)S#si',$duration,$out);
if(empty($out[1])){
preg_match('#PT(.*?)M(.*?)S#si',$duration,$out);
if(empty($out[1])){
preg_match('#PT(.*?)S#si',$duration,$out);
if(empty($out[1])){
return '00:00';
}
}else{
if(strlen($out[1])==1){ $out[1]= '0'.$out[1]; }
if(strlen($out[2])==1){ $out[2]= '0'.$out[2]; }
return $out[1].':'.$out[2];
}
}else{
if(strlen($out[1])==1){ $out[1]= '0'.$out[1]; }
if(strlen($out[2])==1){ $out[2]= '0'.$out[2]; }
if(strlen($out[3])==1){ $out[3]= '0'.$out[3]; }
return $out[1].':'.$out[2].':'.$out[3];
}
}
Use the following php function will return the YouTube video duration..For more exciting codes follow this link more code samples
function getYoutubeDuration($vid)
{
$videoDetails =file_get_contents("https://www.googleapis.com/youtube/v3/videos?id=".$vid."&part=contentDetails&key=AIzaSyDen99uTRRPl9VT_Ra9eAisvZSc4aZDEns");
$videoDetails =json_decode($videoDetails, true);
foreach ($videoDetails['items'] as $vidTime)
{
$youtube_time = $vidTime['contentDetails']['duration'];
preg_match_all('/(\d+)/',$youtube_time,$parts);
$hours = (strlen(floor($parts[0][0]/60))<1)?floor($parts[0][0]/60):'0'.floor($parts[0][0]/60);
$minutes = $parts[0][0]%60; (strlen($parts[0][0]%60)<1)?$parts[0][0]%60:'0'.$parts[0][0]%60;
$seconds = $parts[0][1];(strlen($parts[0][1])<1)?$parts[0][1]:'0'.$parts[0][1];
return $hours.":".$minutes.":".$seconds;
}
}
echo getYoutubeDuration('J1lb3qJgfho');
May be it will be helpful for someone to get duration:
$interval = new \DateInterval($iso8601);
// in seconds:
$seconds = $interval->h * 360 + $interval->i * 60 + $interval->s;
// in "H:i:s" format:
echo $interval->format('%H:%i:%s');
As YouTube (Google) like to be difficult, they opt for non-standard formatting. So standard functions don't always work.
As such, I made this for my need's.
$length = $data['items'] ..... ['duration'];
$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);
Solution with named groups
PT((?P<hours>\d+)H)?((?P<minutes>\d+)M)?((?P<seconds>\d+)S)?
Examples can be found here https://regex101.com/r/wU3hT2/114
Python function:
def yt_time_to_seconds(time):
regex_string = 'PT((?P<hours>\d+)H)?((?P<minutes>\d+)M)?((?P<seconds>\d+)S)?'
regex = re.compile(regex_string)
match = regex.match(time)
if match:
hours = int(match.group('hours'))
minutes = int(match.group('minutes'))
seconds = int(match.group('seconds'))
return hours * 60 * 60 + minutes * 60 + seconds
return 0
it worked perfectly for me 100%, only you should have \ DateInterval as root
function NormalizeDuration($duration){ //pass your time
$start = new \DateTime('@0');
$start->add(new \DateInterval($duration));
return $start->format('H:i:s'); //format
}
来源:https://stackoverflow.com/questions/19562195/converting-youtube-data-api-v3-video-duration-format-to-standard-time-in-php