【问题标题】:Convert YouTube API duration (ISO 8601 duration in the format) to h:m:s , when format without "T" in javascript将 YouTube API 持续时间(格式中的 ISO 8601 持续时间)转换为 h:m:s ,当 JavaScript 中没有“T”的格式时
【发布时间】:2015-09-25 08:40:15
【问题描述】:

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

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

【问题讨论】:

  • PT1D - 也不行,和P1D一样,我试过...
  • 哦,现在我明白了。我以为您遇到了“P1H”的问题,但您似乎遇到了“P1D”的问题,正如您在 OP 中所写的那样。傻我……你只需要T?
  • 顺便说一句,我不确定年份和月份的值是否合适,应该有一些闰年和不同月份长度的余量,请参阅ISO 8601 duration and time stamps in SCORM 2004,它建议1 month = ((365 * 4) + 1)/48 days 并使用@ 987654326@,而 OP 中的代码分别使用 30 天和 365 天(所以 12 个月!= 1 年乘以 5.25 天)。

标签: javascript youtube formatting duration


【解决方案1】:

要修复 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>');
 });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-04
    • 1970-01-01
    • 2019-01-04
    • 2021-01-11
    • 1970-01-01
    • 1970-01-01
    • 2016-07-23
    相关资源
    最近更新 更多