как преобразовать PT2H34M25S в 2:34:25
Я искал и использовал этот код. Я новичок в регулярном выражении, может кто-нибудь объяснить это? и помогите мне с моей проблемой
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; }
но этот код дает мне только HH: MM
поэтому немой нашел решение:
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; }
Вы должны взглянуть на свою переменную $parts
после ее создания.
var_dump($parts);
Сравните этот результат с тем, как вы определяете свои переменные. После этого он должен выглядеть довольно очевидно.
Я предполагаю, что мой следующий вопрос после этого – какие вариации строки времени ввода вы ожидаете и какую проверку вы будете делать? Изменения формата ввода, которые вы хотите обработать, будут влиять на сложность написанного кода.
Изменить: здесь обновленная функция для обработки отсутствующих числовых значений (если часы или минуты опущены) и секунд / часов более 60 (не уверен, что это когда-либо произойдет). Это не подтверждает метку чисел:
Для проверки правильности ввода строки может быть добавлена дополнительная проверка.
<?php function covtime($youtube_time) { preg_match_all('/(\d+)/',$youtube_time,$parts); // Put in zeros if we have less than 3 numbers. if (count($parts[0]) == 1) { array_unshift($parts[0], "0", "0"); } elseif (count($parts[0]) == 2) { array_unshift($parts[0], "0"); } $sec_init = $parts[0][2]; $seconds = $sec_init%60; $seconds_overflow = floor($sec_init/60); $min_init = $parts[0][1] + $seconds_overflow; $minutes = ($min_init)%60; $minutes_overflow = floor(($min_init)/60); $hours = $parts[0][0] + $minutes_overflow; if($hours != 0) return $hours.':'.$minutes.':'.$seconds; else return $minutes.':'.$seconds; }
Для достижения этого вы можете использовать класс DateTime для PHP. Это решение намного проще и будет работать, даже если формат величин в строке будет в другом порядке. В таких случаях регрессионное решение будет (скорее всего) нарушено.
В PHP PT2H34M25S
является допустимой строкой периода даты и понимается парсером DateTime. Затем мы воспользуемся этим фактом и просто добавим его в эпоху Unix, используя метод add()
. Затем вы можете отформатировать итоговую дату для получения требуемых результатов:
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');
демонстрация
Решения Amal и Pferate великолепны! Тем не менее, решение Amal продолжает давать мне 1 ч. Ниже мое решение, которое совпадает с Amal, но разностным подходом, и эта работа для меня.
$date = new DateTime('1970-01-01'); $date->add(new DateInterval('PT2H34M25S')); echo $date->format('H:i:s')
datetime->add()
ссылка
Вот мое решение, которое обрабатывает отсутствующие H, M или S (протестируйте видео с сообщенной длиной 1:00:01, и вы увидите проблему с другими ответами). Секунды представлены как 0:01, но если вы хотите изменить это, просто измените последнее else на elseif($M>0)
и добавьте else в секундах, например 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"; } }
Это мое решение, тест завершен!
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;
Вот полный код для получения, конвертирования и отображения продолжительности видео
$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') ;
Замените xxxxxxx своими ключевыми результатами API: 13:07
Почему осложнение. Думайте нестандартно.
$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);
ОК. preg_replace действительно не требуется, но я полагаю, что он гарантирует только номера.
Затем для моего форматирования (который вы можете делать, как угодно, без ограничений)
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';
Попробуйте выполнить следующую функцию:
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; }
Вы можете попробовать это –
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 и DateInterval не работают в Yii или некоторой версии php. Так что это мое решение. Его работа со мной.
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; }