问题
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
回答1:
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];
回答2:
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.
回答3:
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);
}
回答4:
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 :)
回答5:
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;
回答6:
##:##:## 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];
}
}
回答7:
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');
回答8:
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');
回答9:
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);
回答10:
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
回答11:
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