如何将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;
}
使用 DateTime 类
您可以使用PHP的DateTime类来实现此目的。此解决方案要简单得多,即使字符串中数量的格式顺序不同,也可以工作。在这种情况下,正则表达式解决方案(很可能(会中断。
在 PHP 中,PT2H34M25S
是一个有效的日期周期字符串,由 DateTime 解析器理解。然后我们利用这个事实,并使用add()
方法将其添加到 Unix 时代。然后,您可以设置结果日期的格式以获得所需的结果:
function covtime($youtube_time){
if($youtube_time) {
$start = new DateTime('@0'); // Unix epoch
$start->add(new DateInterval($youtube_time));
$youtube_time = $start->format('H:i:s');
}
return $youtube_time;
}
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 e.g. PT1M3S to HH:MM:SS
// updated to handle videos days long e.g. 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";
}
}
$parts
变量后,您应该查看它。
var_dump($parts);
将该输出与定义变量的方式进行比较。 在那之后,它应该非常明显地脱颖而出。
我想我之后的下一个问题是你期待输入时间字符串的哪些变化,你将进行什么验证? 要处理的输入格式的变化将影响实际编写代码的复杂性。
编辑:这是一个更新的函数,用于处理缺失的数值(如果省略小时或分钟(和超过 60 的秒/小时(不确定这是否会发生(。 这不会验证数字的标签:
- 1 个数字:假设是秒
- 2 个数字:假设是分钟、秒 3
- 个或更多数字:假设前 3 个数字是小时、分钟、秒(忽略另一个数字(
可以添加更多验证来研究验证输入字符串。
<?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;
}
的解决方案,测试完成!
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;
我使用两个类,一个用于调用YouTube API,一个用于转换时间。 这里被简化。
如您所见,YouTubeGet 是一个静态类,但并非必须如此。 然而,YouTubeDateInterval必须是一个实例,因为DateInterval的工作方式(正在扩展(。
class YouTubeGet{
static public function get_duration($video_id, $api_key){
// $youtube_api_key
$url = "https://www.googleapis.com/youtube/v3/videos?id={$video_id}&part=contentDetails&key={$api_key}";
// Get and convert. This example uses wordpress wp_remote_get()
// this could be replaced by file_get_contents($url);
$response = wp_remote_get($url);
// if using file_get_contents(), then remove ['body']
$result = json_decode($response['body'], true);
// I've converted to an array, but this works fine as an object
if(isset($result['items'][0]['contentDetails']['duration'])){
$duration = $result['items'][0]['contentDetails']['duration'];
return self::convtime($duration);
}
return false;
}
static protected function convtime($youtube_time){
$time = new YouTubeDateInterval($youtube_time);
return $time->to_seconds();
}
}
class YouTubeDateInterval extends DateInterval {
public function to_seconds()
{
return ($this->y * 365 * 24 * 60 * 60) +
($this->m * 30 * 24 * 60 * 60) +
($this->d * 24 * 60 * 60) +
($this->h * 60 * 60) +
($this->i * 60) +
$this->s;
}
}
用法是将 ISO 8601 日期传递给 YouTubeDateInterval。
$time = new YouTubeDateInterval('PT2H34M25S');
$duration_in_seconds = $time->to_seconds();
或传递 YouTube 获取 API 和视频 ID 密钥
$duration_in_seconds = YouTubeGet::get_duration('videoIdString','YouTubeApiKeyString');
这是获取,转换和显示视频持续时间的完整代码
$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
试试这个会给你的持续时间几秒钟
function video_length($youtube_time)
{
$duration = new DateInterval($youtube_time);
return $duration->h * 3600 + $duration->i * 60 + $duration->s;
}
$duration = new DateInterval($data['items'][0]['contentDetails']['duration']);
echo $duration->format('%H:%i:%s');
function getDuration($duration): string
{
preg_match_all("/P(d+D)?T(d+H)?(d+M)?(d+S)?/", $duration, $m);
$days = empty($m[1][0]) ? 0 : substr($m[1][0], 0, -1);
$hours = empty($m[2][0]) ? 0 : substr($m[2][0], 0, -1);
$minutes = empty($m[3][0]) ? 0 : substr($m[3][0], 0, -1);
$seconds = empty($m[4][0]) ? 0 : substr($m[4][0], 0, -1);
$hours += ($days * 24);
$hours = sprintf("%02d", $hours);
$minutes = sprintf("%02d", $minutes);
$seconds = sprintf("%02d", $seconds);
return "$hours:$minutes:$seconds";
}
例:
input: PT2H34M25S
output: 02:34:25
input: P1DT3H12M8S
output: 27:12:08
我已经通过使用use CarbonCarbonInterval
库完成了此操作。
public static function convert_youtube_duration_to_normal(string $youtube_time)
{
return CarbonInterval::create($youtube_time)->forHumans();
}
Functions::convert_youtube_duration_to_normal('PT4M25S')
作为输出返回"4 minutes 25 seconds"
尝试以下函数:
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;
}
为什么会变得复杂。跳出框框思考。
$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';