如何将YouTube API持续时间(ISO 8601格式中的PT#M#S)转换为秒数

17

如何使用JavaScript处理格式为PT#M#S的日期时间?

例如:PT5M33S

我想将其输出为hh:mm:ss


2
Fiddle:https://jsfiddle.net/Daugilas/kbeb0p99/1/ - Daugilas Kakaras
1
@Daugilas Kakaras,非常好!但是您需要更新函数。当格式为P1D(一天)时,函数无法正常工作。 - Serhio g. Lazin
2
@Serhiog.Lazin,真的 - 已更新:https://jsfiddle.net/kbeb0p99/4/ *经过相当长的时间 :) - Daugilas Kakaras
请尝试使用以下链接:https://gist.github.com/Fauntleroy/5167736 - cuddlemeister
6个回答

26

这是获取总秒数和其他时间组成部分的基本代码。

我对此感到不安,因为规则说任何时候你想要日期逻辑,你都不应该做 :) 但无论如何,接下来就是 - 谷歌使其不易,提供了在getduration播放器API中提供总秒数,并在gdata API中提供完全不同的格式。

          var reptms = /^PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?$/;
          var hours = 0, minutes = 0, seconds = 0, totalseconds;

          if (reptms.test(input)) {
            var matches = reptms.exec(input);
            if (matches[1]) hours = Number(matches[1]);
            if (matches[2]) minutes = Number(matches[2]);
            if (matches[3]) seconds = Number(matches[3]);
            totalseconds = hours * 3600  + minutes * 60 + seconds;
          }

谢谢,我稍微调整了一下,现在它正好按照我的需求工作。 - Nicholas
duration: "PT26M"怎么样? - Hamzeh Soboh
输入格式也可以包含小数。例如 PT36.53S。这是更新后的正则表达式:^PT(?:(\d+\.*\d*)H)?(?:(\d+\.*\d*)M)?(?:(\d+\.*\d*)S)?$ - Snebhu

5

以下是如何通过 Youtube API (v3) 简单获取YouTube视频数据并将视频时长(ISO 8601)转换为秒数的方法。请不要忘记在URL中更改{ YOUR VIDEO ID }{ YOUR KEY }属性,以使用您自己的视频ID公共Google密钥。 您可以访问Google开发人员控制台创建公共密钥。

  $.ajax({
       url: "https://www.googleapis.com/youtube/v3/videos?id={ YOUR VIDEO ID }&part=contentDetails&key={ YOUR KEY }",
       dataType: "jsonp",
       success: function (data) { youtubeCallback (data); }
  });

    function youtubeCallback(data) {

        var duration = data.items[0].contentDetails.duration;
        alert ( convertISO8601ToSeconds (duration) );
    }        

    function convertISO8601ToSeconds(input) {

        var reptms = /^PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?$/;
        var hours = 0, minutes = 0, seconds = 0, totalseconds;

        if (reptms.test(input)) {
            var matches = reptms.exec(input);
            if (matches[1]) hours = Number(matches[1]);
            if (matches[2]) minutes = Number(matches[2]);
            if (matches[3]) seconds = Number(matches[3]);
            totalseconds = hours * 3600  + minutes * 60 + seconds;
        }

        return (totalseconds);
    }

duration: "PT26M"怎么样? - Hamzeh Soboh

1
虽然这些答案在技术上是正确的,但如果您计划处理大量时间和持续时间,请查看momentjs。还要查看moment-duration-formats,它使格式化持续时间与常规momentjs时间一样简单。
这两个模块使得操作变得非常容易,以下是一个例子。
moment.duration('PT5M33S').format('hh:mm:ss')

这将输出05:33。还有许多其他用途。

尽管YouTube使用ISO8601格式是因为它是一个标准,所以请记住这一点。


类型错误:moment.duration(...).format不是函数。我在Node 8.10和moment 2.22.2中遇到了这个问题。 - Abhi
@Abhi 你安装了moment-duration-format包并且引用它了吗? - tehduder9
我使用了这样的方式:moment().day("Monday").year(year_val).week(week_val).format('YYYY-MM-DD'),它也成功运行了。 - Abhi
@Abhi,所以你没有阅读包的文档?好吧。 - tehduder9

1

目前在2023年,Moment.js处于遗留模式。

您可以使用Luxon.js(Moment.js的后代)的Duration类来解析ISO8601持续时间。

import { Duration } from 'luxon'

// OP's desired hh:mm:ss format
> Duration.fromISO('PT20S').toISOTime({suppressMilliseconds: true})
'00:00:20'


// other useful outputs

> Duration.fromISO('PT2M42S').toHuman()
'2 minutes, 42 seconds'

> Duration.fromISO('PT1H16M5S').toMillis()
4565000

> Duration.fromISO('P1DT2H1S').toObject()
{ days: 1, hours: 2, seconds: 1 }

0

我通过检查单位(H,M,S)左侧两个索引处的字符并检查其是否为数字来解决此问题。如果不是数字,则该单位为单个数字,我会在前面添加一个额外的“0”。否则,我返回两位数。

   function formatTimeUnit(input, unit){
     var index = input.indexOf(unit);
     var output = "00"
    if(index < 0){
      return output; // unit isn't in the input
    }

    if(isNaN(input.charAt(index-2))){
      return '0' + input.charAt(index-1);
    }else{
      return input.charAt(index-2) + input.charAt(index-1);
    }
  }

我会计算小时、分钟和秒。如果输入中没有小时,我也会忽略它,这当然是可选的。
    function ISO8601toDuration(input){
     var H = formatTimeUnit(input, 'H');
     var M = formatTimeUnit(input, 'M');
     var S = formatTimeUnit(input, 'S');

    if(H == "00"){
      H = "";
    }else{
      H += ":"
    }

    return H  + M + ':' + S ;
  }

然后就像这样调用它

  duration = ISO8601toDuration(item.duration);

我使用这个来格式化YouTube数据API视频时长。 希望这能帮助到某些人。


0

最简单的方法是使用moment-duration-formats。不过,以下是一个自定义函数,将YouTube API持续时间响应转换为hh:mm:ss格式。

const convertISO8601ToStringWithColons = string => {
        let hours, minutes, seconds;

        if (string.includes("H")) {
            hours = string.slice(2, string.indexOf("H"));
        } else {
            hours = false;
        }

        if (string.includes("S")) {
            // checks if number is one-digit and inserts 0 in front of it
            if (isNaN(parseInt(string.charAt(string.indexOf("S") - 2)))) {
                seconds = "0" + string.charAt(string.indexOf("S") - 1)
            } else {
                seconds = string.slice(-3, -1)
            }
        } else {
            seconds = "00"
        }
        
        // determines how minutes are displayed, based on existence of hours and minutes
        if (hours) {
            if (string.includes("M")) {
                if (string.indexOf("M") - string.indexOf("H") === 3) {
                    minutes = string.slice(string.indexOf("H") + 1, string.indexOf("M"))
                } else {
                    minutes = "0" + string.charAt(string.indexOf("M") - 1)
                }
            } else {
                minutes = "00"
            }
        } else {
            if (string.includes("M")) {
                minutes = string.slice(2, (string.indexOf("M")))
            } else {
                minutes = "0"
            }   
        }

        // distinction because livestreams (P0D) are not considered
        return string === "P0D" ? "Live" : `${hours ? hours + ":" : ""}${minutes}:${seconds}`
    }
    
const textExamples = ["PT11H57M30S", "PT7H2M", "PT10H37S", "PT8H", "PT4M58S", "PT39M", "PT7S", "P0D"]
textExamples.forEach(element => {
    console.log(convertISO8601ToStringWithColons(element))
});


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接