Converting Youtube Data API V3 video duration form

2019-01-17 20:14发布

I'm trying to convert ISO 8601 string to seconds in JS/Node. The best I could come up with was:

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
}

It works when I input strings such as "PT48S", "PT3M20S" or "PT3H2M31S", but fails miserably if the string is "PT1H11S". Does anyone have a better idea?

11条回答
看我几分像从前
2楼-- · 2019-01-17 20:43

This is not java specific, but i would like to add JAVA snippet as that may helpful to other users

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);
查看更多
该账号已被封号
3楼-- · 2019-01-17 20:45

My solution:

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;
}

Fiddle

查看更多
Root(大扎)
4楼-- · 2019-01-17 20:45
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;
}

works for these cases:

PT1H
PT23M
PT45S
PT1H23M
PT1H45S
PT23M45S
PT1H23M45S
查看更多
Lonely孤独者°
5楼-- · 2019-01-17 20:47

You can find a very simple PHP solution here - How To Convert Youtube API Time (ISO 8601 String Video Duration) to Seconds In PHP - Code

This function convert_time() takes one parameter as input - the Youtube API Time (Video Duration) which is in ISO 8601 string format and returns its duration in seconds.

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 Some Inputs:

"PT2M23S" => 143
"PT2M" => 120
"PT28S" => 28
"PT5H22M31S" => 19351
"PT3H" => 10800
"PT1H6M" => 3660
"PT1H6S" => 3606
查看更多
beautiful°
6楼-- · 2019-01-17 20:50

Assuming the input is valid, we can use the regex exec method to iterate on the string and extract the group sequentially:

const YOUTUBE_TIME_RE = /(\d+)([HMS])/g;
const YOUTUBE_TIME_UNITS = {
    'H': 3600,
    'M': 60,
    'S': 1
}

/**
 * Returns the # of seconds in a youtube time string
 */
function parseYoutubeDate(date: string): number {
    let ret = 0;
    let match: RegExpExecArray;
    while (match = YOUTUBE_TIME_RE.exec(date)) {
        ret += (YOUTUBE_TIME_UNITS[match[2]]) * Number(match[1]);
    }
    return ret;
}
查看更多
劳资没心,怎么记你
7楼-- · 2019-01-17 20:51

I've written a CoffeeScript variation (you can easily compile it at coffeescript.org when desired)

DIFFERENCE: the returning duration comes in a human readable format (e.g. 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

I've also implemented this helper function to fill < 10 values with a leading zero:

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

3nj0y!!!

查看更多
登录 后发表回答