2015-09-25 68 views
0

我已经检查的最类似的问题,而这一次是有帮助转换YouTube API持续时间(格式为ISO 8601持续时间),以H:M:S,时制,没有 “T” 在JavaScript

> 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”的视频,上面的函数无法格式化它。

+0

PT1D - 没有作品也一样P1D,我已经试过... –

+1

哦,现在我明白了。我以为你遇到了与“P1H”有关的问题,但是看起来你遇到了与“P1D”有关的问题,就像你在OP中写的一样。傻我......你只需要'T?'。 – RobG

+1

顺便说一句,我不确定年份和月份的数值是否合适,应该有一些闰年补贴和不同的月份长度,请参阅[* SCORM 2004 *中的ISO 8601持续时间和时间戳](http:// www建议1个月=((365 * 4)+ 1)/ 48天,并使用'1年= 365.25天',而代码为.ostyn.com/standards/scorm/samples/ISOTimeForSCORM.htm#durationfmt)在OP中分别使用30天和365天(因此12个月!= 1年5.25天)。 – RobG

回答

2

要修复OP中的代码,您需要使T是可选的,因此请用T?代替T

使用年份和月份的数值似乎不适合(见ISO 8601 duration and time stamps in SCORM 2004),天在一年的数量更好approimated为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>'); 
 
});

+0

谢谢,太棒了! –

相关问题