在JavaScript / Node.js中将Youtube Data API V3video持续时间格式转换为秒数

我试图将ISO 8601string转换为JS /节点秒。 我能想到的最好的是:

function convert_time(duration) { var a = duration.match(/\d+/g) var duration = 0 if(a.length == 3) { duration = duration + parseInt(a[0]) * 3600; duration = duration + parseInt(a[1]) * 60; duration = duration + parseInt(a[2]); } if(a.length == 2) { duration = duration + parseInt(a[0]) * 60; duration = duration + parseInt(a[1]); } if(a.length == 1) { duration = duration + parseInt(a[0]); } return duration } 

当input“PT48S”,“PT3M20S”或“PT3H2M31S”等string时,它将起作用,但如果string是“PT1H11S”,则失败。 有没有人有更好的主意?

我build议这个小黑客来防止你的问题情况:

 function convert_time(duration) { var a = duration.match(/\d+/g); if (duration.indexOf('M') >= 0 && duration.indexOf('H') == -1 && duration.indexOf('S') == -1) { a = [0, a[0], 0]; } if (duration.indexOf('H') >= 0 && duration.indexOf('M') == -1) { a = [a[0], 0, a[1]]; } if (duration.indexOf('H') >= 0 && duration.indexOf('M') == -1 && duration.indexOf('S') == -1) { a = [a[0], 0, 0]; } duration = 0; if (a.length == 3) { duration = duration + parseInt(a[0]) * 3600; duration = duration + parseInt(a[1]) * 60; duration = duration + parseInt(a[2]); } if (a.length == 2) { duration = duration + parseInt(a[0]) * 60; duration = duration + parseInt(a[1]); } if (a.length == 1) { duration = duration + parseInt(a[0]); } return duration } 

小提琴

 function YTDurationToSeconds(duration) { var match = duration.match(/PT(\d+H)?(\d+M)?(\d+S)?/); match = match.slice(1).map(function(x) { if (x != null) { return x.replace(/\D/, ''); } }); var hours = (parseInt(match[0]) || 0); var minutes = (parseInt(match[1]) || 0); var seconds = (parseInt(match[2]) || 0); return hours * 3600 + minutes * 60 + seconds; } 

适用于这些情况:

 PT1H PT23M PT45S PT1H23M PT1H45S PT23M45S PT1H23M45S 

如果你使用的是moment.js,你可以直接调用…

 moment.duration('PT15M33S').asMilliseconds(); 

= 933000毫秒

这是我的解决scheme:

 function parseDuration(duration) { var matches = duration.match(/[0-9]+[HMS]/g); var seconds = 0; matches.forEach(function (part) { var unit = part.charAt(part.length-1); var amount = parseInt(part.slice(0,-1)); switch (unit) { case 'H': seconds += amount*60*60; break; case 'M': seconds += amount*60; break; case 'S': seconds += amount; break; default: // noop } }); return seconds; } 

我的解决scheme

 function convert_time(duration) { var total = 0; var hours = duration.match(/(\d+)H/); var minutes = duration.match(/(\d+)M/); var seconds = duration.match(/(\d+)S/); if (hours) total += parseInt(hours[1]) * 3600; if (minutes) total += parseInt(minutes[1]) * 60; if (seconds) total += parseInt(seconds[1]); return total; } 

小提琴

我写了一个CoffeeScript变体(如果需要,你可以在coffeescript.org上轻松编译它)

差异:返回的持续时间以人类可读的格式(例如04:20,01:05:48)

 String.prototype.parseDuration = -> m = @.match /[0-9]+[HMS]/g res = "" fS = fM = !1 for part in m unit = part.slice -1 val = part.slice 0, part.length - 1 switch unit when "H" then res += val.zeros( 2 ) + ":" when "M" fM = 1 res += val.zeros( 2 ) + ":" when "S" fS = 1 res += if fM then val.zeros 2 else "00:" + val.zeros 2 if !fS then res += "00" res 

我也实现了这个辅助函数来填充<10个前导零的值:

 String.prototype.zeros = ( x ) -> len = @length if !x or len >= x then return @ zeros = "" zeros += "0" for [0..(x-len-1)] zeros + @ 

3nj0y!

你可以在这里find一个非常简单的PHP解决scheme – 如何将Youtube API时间(ISO 8601stringvideo持续时间)转换为PHP中的秒数 – 代码

此函数convert_time()将一个参数作为input – Youtube API时间(video持续时间),采用ISO 8601string格式,并以秒为单位返回持续时间。

 function convert_time($str) { $n = strlen($str); $ans = 0; $curr = 0; for($i=0; $i<$n; $i++) { if($str[$i] == 'P' || $str[$i] == 'T') { } else if($str[$i] == 'H') { $ans = $ans + 3600*$curr; $curr = 0; } else if($str[$i] == 'M') { $ans = $ans + 60*$curr; $curr = 0; } else if($str[$i] == 'S') { $ans = $ans + $curr; $curr = 0; } else { $curr = 10*$curr + $str[$i]; } } return($ans); } 

testing一些input:

 "PT2M23S" => 143 "PT2M" => 120 "PT28S" => 28 "PT5H22M31S" => 19351 "PT3H" => 10800 "PT1H6M" => 3660 "PT1H6S" => 3606 

我遇到了上述解决scheme的问题。 我决定把它写成尽可能钝的。 我也使用我自己的“getIntValue”代替parseInt来获得额外的理智。

只是觉得其他search可能会赞赏更新。

小提琴

  function convertYouTubeTimeFormatToSeconds(timeFormat) { if ( timeFormat === null || timeFormat.indexOf("PT") !== 0 ) { return 0; } // match the digits into an array // each set of digits into an item var digitArray = timeFormat.match(/\d+/g); var totalSeconds = 0; // only 1 value in array if (timeFormat.indexOf('H') > -1 && timeFormat.indexOf('M') == -1 && timeFormat.indexOf('S') == -1) { totalSeconds += getIntValue(digitArray[0]) * 60 * 60; } else if (timeFormat.indexOf('H') == -1 && timeFormat.indexOf('M') > -1 && timeFormat.indexOf('S') == -1) { totalSeconds += getIntValue(digitArray[0]) * 60; } else if (timeFormat.indexOf('H') == -1 && timeFormat.indexOf('M') == -1 && timeFormat.indexOf('S') > -1) { totalSeconds += getIntValue(digitArray[0]); } // 2 values in array else if (timeFormat.indexOf('H') > -1 && timeFormat.indexOf('M') > -1 && timeFormat.indexOf('S') == -1) { totalSeconds += getIntValue(digitArray[0]) * 60 * 60; totalSeconds += getIntValue(digitArray[1]) * 60; } else if (timeFormat.indexOf('H') > -1 && timeFormat.indexOf('M') == -1 && timeFormat.indexOf('S') > -1) { totalSeconds += getIntValue(digitArray[0]) * 60 * 60; totalSeconds += getIntValue(digitArray[1]); } else if (timeFormat.indexOf('H') == -1 && timeFormat.indexOf('M') > -1 && timeFormat.indexOf('S') > -1) { totalSeconds += getIntValue(digitArray[0]) * 60; totalSeconds += getIntValue(digitArray[1]); } // all 3 values else if (timeFormat.indexOf('H') > -1 && timeFormat.indexOf('M') > -1 && timeFormat.indexOf('S') > -1) { totalSeconds += getIntValue(digitArray[0]) * 60 * 60; totalSeconds += getIntValue(digitArray[1]) * 60; totalSeconds += getIntValue(digitArray[2]); } // console.log(timeFormat, totalSeconds); return totalSeconds; } function getIntValue(value) { if (value === null) { return 0; } else { var intValue = 0; try { intValue = parseInt(value); if (isNaN(intValue)) { intValue = 0; } } catch (ex) { } return Math.floor(intValue); } } 

python

它通过一次parsinginputstring1字符来工作,如果字符是数字,它只是简单地将它添加到正在parsing的当前值中(string添加,而不是math添加)。 如果是“wdhms”之一,则将当前值分配给适当的variables(星期,星期,小时,分钟,秒),然后将值重置为准备下一个值。 最后,总结5个parsing值的秒数。

 def ytDurationToSeconds(duration): #eg P1W2DT6H21M32S week = 0 day = 0 hour = 0 min = 0 sec = 0 duration = duration.lower() value = '' for c in duration: if c.isdigit(): value += c continue elif c == 'p': pass elif c == 't': pass elif c == 'w': week = int(value) * 604800 elif c == 'd': day = int(value) * 86400 elif c == 'h': hour = int(value) * 3600 elif c == 'm': min = int(value) * 60 elif c == 's': sec = int(value) value = '' return week + day + hour + min + sec 

这不是特定于java,但我想添加JAVA片段,因为这可能有助于其他用户

 String duration = "PT1H23M45S"; Pattern pattern = Pattern.compile("PT(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)S)?"); Matcher matcher = pattern.matcher(duration); long sec = 0; long min = 0; long hour = 0; if (matcher.find()) { if(matcher.group(1)!=null) hour = NumberUtils.toInt(matcher.group(1)); if(matcher.group(2)!=null) min = NumberUtils.toInt(matcher.group(2)); if(matcher.group(3)!=null) sec = NumberUtils.toInt(matcher.group(3)); } long totalSec = (hour*3600)+(min*60)+sec; System.out.println(totalSec);