将YouTube API持续时间(格式中的ISO 8601持续时间)转换为h:m:s,当javascript中没有“T”的格式时

时间:2015-09-25 08:40:16

标签: javascript youtube formatting duration

我检查过大多数类似的问题,这个问题很有帮助

> function parseDuration(PT) {   var output = [];   var durationInSec =
> 0;   var matches =
> PT.match(/P(?:(\d*)Y)?(?:(\d*)M)?(?:(\d*)W)?(?:(\d*)D)?T(?:(\d*)H)?(?:(\d*)M)?(?:(\d*)S)?/i);
> var parts = [
>     { // years
>       pos: 1,
>       multiplier: 86400 * 365
>     },
>     { // months
>       pos: 2,
>       multiplier: 86400 * 30
>     },
>     { // weeks
>       pos: 3,
>       multiplier: 604800
>     },
>     { // days
>       pos: 4,
>       multiplier: 86400
>     },
>     { // hours
>       pos: 5,
>       multiplier: 3600
>     },
>     { // minutes
>       pos: 6,
>       multiplier: 60
>     },
>     { // seconds
>       pos: 7,
>       multiplier: 1
>     }   ];
>      for (var i = 0; i < parts.length; i++) {
>     if (typeof matches[parts[i].pos] != 'undefined') {
>       durationInSec += parseInt(matches[parts[i].pos]) * parts[i].multiplier;
>     }   }
>      // Hours extraction   if (durationInSec > 3599) {
>     output.push(parseInt(durationInSec / 3600));
>     durationInSec %= 3600;   }   if (durationInSec >= 86399) {
>     output.push("24:00");    }     // Minutes extraction with leading zero   output.push(('0' + parseInt(durationInSec / 60)).slice(-2));  
> // Seconds extraction with leading zero   output.push(('0' +
> durationInSec % 60).slice(-2));
>      return output.join(':'); };
https://jsfiddle.net/Daugilas/kbeb0p99/1/来自@Daugilas Kakaras的回答

但我发现一个格式为P1D(一天)的视频,没有“T”,上面的功能无法格式化。

1 个答案:

答案 0 :(得分:2)

要修复OP中的代码,您需要将T设为可选,因此请将T替换为T?

年份和月份使用的值似乎不合适(请参阅ISO 8601 duration and time stamps in SCORM 2004),一年中的天数更好地归为365.25 days,而在一个月内更新为365.25 * 4 / 48 days虽然做持续时间超过1个月的算术对于像这样的简单函数来说是非常有问题的。

以下是一个替代函数,它不测试输入字符串的有效性,它可能应该和毫秒到h:mm:ss.sss的转换应该是一个单独的函数,但我会把它留给其他

/*   @param {string} s - ISO8601 format duration
**
**                       P[yY][mM][dD][T[hH][mM][s[.s]S]]
**
**   @returns {string} - time in h:mm:ss format
**
**   1 year is 365.25 days
**   1 months is averaged over 4 years: (365*4+1)/48
**/
function convertISODurationToHMS(s) {
  var T = 'date';
  var d = 8.64e7;
  var h = d/24;
  var m = h/60;
  var multipliers = {date: {y:d*365.25, m:d*(365*4+1)/48, d:d},
                     time: {h:h, m:m, s:1000}};
  var re = /[^a-z]+|[a-z]/gi;

  // Tokenise with match, then process with reduce
  var time = s.toLowerCase().match(/p|t|\d+\.?\d*[ymdhs]/ig).reduce(function(ms, v) {
    if (v == 'p') return ms;
    if (v == 't') {
      T = 'time';
      return ms;
    }
    var b = v.match(re);
    return ms + b[0] * multipliers[T][b[1]];
  }, 0);
  
  // Converting ms to h:mm:ss should be a separate function
  return (time/h|0) + ':'
       + ('0' + ((time%h / m) |0)).slice(-2) + ':'
       + ('0' + (time%m/1000).toFixed(3)).slice(-6);
}

// Some tests
['P1D',
 'PT1M',
 'PT1M2.3S',
 'P1DT1H1M2.345S',
 'P1DT1H1M2.34S',
  'P1M',
  'P1YT1H1M56.234S']
  .forEach(function(v){
   document.write(v + ': ' + convertISODurationToHMS(v) + '<br>');
 });