【问题标题】:How to convert Youtube API V3 duration in Java如何在 Java 中转换 Youtube API V3 持续时间
【发布时间】:2013-05-24 15:17:12
【问题描述】:

Youtube V3 API 使用 ISO8601 时间格式来描述视频的时长。 像“PT1M13S”这样的东西。现在我想将字符串转换为秒数(例如本例中的 73)。

是否有任何 Java 库可以帮助我轻松完成 Java 6 下的任务? 还是我必须自己完成正则表达式任务?

编辑

最后我接受@Joachim Sauer 的回答

Joda的示例代码如下。

PeriodFormatter formatter = ISOPeriodFormat.standard();
Period p = formatter.parsePeriod("PT1H1M13S");
Seconds s = p.toStandardSeconds();

System.out.println(s.getSeconds());

【问题讨论】:

  • 是否重复?这个问题是针对日期格式的。
  • 真的不明白在这种情况下如何使用 SimpleDateFormat 来获取秒数,因为它不是日期格式。谢谢!
  • @nhahtdh:它不是重复的,因为链接到的处理日期字符串,而这是一个持续时间字符串!

标签: java youtube-api time-format


【解决方案1】:

Joda Time 是任何类型的时间相关函数的首选库。

对于这种特定情况,ISOPeriodFormat.standard() 返回一个可以解析和格式化该格式的PeriodFormatter

生成的对象是a Period (JavaDoc)。获取实际秒数将是period.toStandardSeconds().getSeconds(),但我建议您将持续时间作为Period 对象处理(为了便于处理和类型安全)。

编辑:来自未来的我的注释:这个答案已经有好几年了。 Java 8 带来了java.time.Duration,它也可以解析这种格式,并且不需要外部库。

【讨论】:

  • 谢谢!我先看看
【解决方案2】:

Java 8 中的解决方案:

Duration.parse(duration).getSeconds()

【讨论】:

  • 您必须确保您的 JAVA_HOME 设置为 JDK8 或您的 IDE 配置为使用 JDK8。我必须添加 maven 插件才能使上述代码在我的 IntelliJ IDEA 17 中工作。插件 URL:mvnrepository.com/artifact/org.apache.maven.plugins/…
  • 在Android中将这个添加到gradle:compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 }(但它仅适用于26 API,所以暂时不建议使用它)
【解决方案3】:

我可能会迟到,其实很简单。尽管可能有更好的方法来做到这一点。持续时间以毫秒为单位。

public long getDuration() {
    String time = "PT15H12M46S".substring(2);
    long duration = 0L;
    Object[][] indexs = new Object[][]{{"H", 3600}, {"M", 60}, {"S", 1}};
    for(int i = 0; i < indexs.length; i++) {
        int index = time.indexOf((String) indexs[i][0]);
        if(index != -1) {
            String value = time.substring(0, index);
            duration += Integer.parseInt(value) * (int) indexs[i][1] * 1000;
            time = time.substring(value.length() + 1);
        }
    }
    return duration;
}

【讨论】:

    【解决方案4】:

    这是我的解决方案

    public class MyDateFromat{
        public static void main(String args[]){
            String ytdate = "PT1H1M15S";
            String result = ytdate.replace("PT","").replace("H",":").replace("M",":").replace("S","");
            String arr[]=result.split(":");
            String timeString = String.format("%d:%02d:%02d", Integer.parseInt(arr[0]), Integer.parseInt(arr[1]),Integer.parseInt(arr[2]));
            System.out.print(timeString);       
        }
    }
    

    如果你想在几秒钟内转换,它将返回一个 H:MM:SS 格式的字符串,你可以使用

    int timeInSedonds = int timeInSecond = Integer.parseInt(arr[0])*3600 + Integer.parseInt(arr[1])*60 +Integer.parseInt(arr[2])
    

    注意:可能会抛出异常,请根据result.split(":");的大小处理

    【讨论】:

    • stackoverflow 上最简单最好的解决方案
    • 请注意,这对于缺少 H、M 或 S 的时间是准确的(例如 PT35M10S 或 PT1H30S)。不保证 H、M 或 S 出现在字段中
    【解决方案5】:

    这可能会帮助一些不想要任何库而只想要一个简单函数的人,

    String duration="PT1H11M14S";
    

    这是函数,

    private String getTimeFromString(String duration) {
        // TODO Auto-generated method stub
        String time = "";
        boolean hourexists = false, minutesexists = false, secondsexists = false;
        if (duration.contains("H"))
            hourexists = true;
        if (duration.contains("M"))
            minutesexists = true;
        if (duration.contains("S"))
            secondsexists = true;
        if (hourexists) {
            String hour = "";
            hour = duration.substring(duration.indexOf("T") + 1,
                    duration.indexOf("H"));
            if (hour.length() == 1)
                hour = "0" + hour;
            time += hour + ":";
        }
        if (minutesexists) {
            String minutes = "";
            if (hourexists)
                minutes = duration.substring(duration.indexOf("H") + 1,
                        duration.indexOf("M"));
            else
                minutes = duration.substring(duration.indexOf("T") + 1,
                        duration.indexOf("M"));
            if (minutes.length() == 1)
                minutes = "0" + minutes;
            time += minutes + ":";
        } else {
            time += "00:";
        }
        if (secondsexists) {
            String seconds = "";
            if (hourexists) {
                if (minutesexists)
                    seconds = duration.substring(duration.indexOf("M") + 1,
                            duration.indexOf("S"));
                else
                    seconds = duration.substring(duration.indexOf("H") + 1,
                            duration.indexOf("S"));
            } else if (minutesexists)
                seconds = duration.substring(duration.indexOf("M") + 1,
                        duration.indexOf("S"));
            else
                seconds = duration.substring(duration.indexOf("T") + 1,
                        duration.indexOf("S"));
            if (seconds.length() == 1)
                seconds = "0" + seconds;
            time += seconds;
        }
        return time;
    }
    

    【讨论】:

      【解决方案6】:

      您可以使用标准 SimpleDateFormatString 解析为 Date 并从那里进行处理:

      DateFormat df = new SimpleDateFormat("'PT'mm'M'ss'S'");
      String youtubeDuration = "PT1M13S";
      Date d = df.parse(youtubeDuration);
      Calendar c = new GregorianCalendar();
      c.setTime(d);
      c.setTimeZone(TimeZone.getDefault());
      System.out.println(c.get(Calendar.MINUTE));
      System.out.println(c.get(Calendar.SECOND));
      

      【讨论】:

      • 警告:持续时间不是日期,并且将其视为一个大罐蠕虫(想想闰年、闰秒、时区……)。
      • 我同意,但是对于将秒数从定义的格式中提取出来的简单任务,它运行良好。
      • 除了格式可以包括小时,不一定包括分钟(PT10SPT1H1M1S 将是有效的,根据 ISO8601)。
      • 这是 Java SimpleDateFormat 实现的一个标准问题,对于有/没有任何小时和/或分钟的情况,可以通过使用多个实例再次轻松解决。我不是提供一个 100% 的解决方案,而是一个起点。与您之前的评论的联系在哪里?
      • 是的,但是解决这个问题会使解决方案变得越来越复杂,可能比编写适当的解析器更复杂,肯定使用更复杂> 一个合适的解析器。我正在回复您的上一条评论。
      【解决方案7】:

      如果您可以确定输入的有效性并且不能使用正则表达式,我会使用此代码(以毫秒为单位返回):

      Integer parseYTDuration(char[] dStr) {
          Integer d = 0;
      
          for (int i = 0; i < dStr.length; i++) {
              if (Character.isDigit(dStr[i])) {
                  String digitStr = "";
                  digitStr += dStr[i];
                  i++;
                  while (Character.isDigit(dStr[i])) {
                      digitStr += dStr[i];
                      i++;
                  }
      
                  Integer digit = Integer.valueOf(digitStr);
      
                  if (dStr[i] == 'H')
                      d += digit * 3600;
                  else if (dStr[i] == 'M')
                      d += digit * 60;
                  else
                      d += digit;
              }
          }
      
          return d * 1000;
      }
      

      【讨论】:

        【解决方案8】:

        我已经实现了这个方法,到目前为止它已经奏效了。

        private String timeHumanReadable (String youtubeTimeFormat) {
        // Gets a PThhHmmMssS time and returns a hh:mm:ss time
        
            String
                    temp = "",
                    hour = "",
                    minute = "",
                    second = "",
                    returnString;
        
            // Starts in position 2 to ignore P and T characters
            for (int i = 2; i < youtubeTimeFormat.length(); ++ i)
            {
                // Put current char in c
                char c = youtubeTimeFormat.charAt(i);
        
                // Put number in temp
                if (c >= '0' && c <= '9')
                    temp = temp + c;
                else
                {
                    // Test char after number
                    switch (c)
                    {
                        case 'H' : // Deal with hours
                            // Puts a zero in the left if only one digit is found
                            if (temp.length() == 1) temp = "0" + temp;
        
                            // This is hours
                            hour = temp;
        
                            break;
        
                        case 'M' : // Deal with minutes
                            // Puts a zero in the left if only one digit is found
                            if (temp.length() == 1) temp = "0" + temp;
        
                            // This is minutes
                            minute = temp;
        
                            break;
        
                        case  'S': // Deal with seconds
                            // Puts a zero in the left if only one digit is found
                            if (temp.length() == 1) temp = "0" + temp;
        
                            // This is seconds
                            second = temp;
        
                            break;
        
                    } // switch (c)
        
                    // Restarts temp for the eventual next number
                    temp = "";
        
                } // else
        
            } // for
        
            if (hour == "" && minute == "") // Only seconds
                returnString = second;
            else {
                if (hour == "") // Minutes and seconds
                    returnString = minute + ":" + second;
                else // Hours, minutes and seconds
                    returnString = hour + ":" + minute + ":" + second;
            }
        
            // Returns a string in hh:mm:ss format
            return returnString; 
        
        }
        

        【讨论】:

          【解决方案9】:

          我自己做的

          我们试试

          import java.text.DateFormat;
          import java.text.ParseException;
          import java.text.SimpleDateFormat;
          import java.util.Calendar;
          import java.util.Date;
          import java.util.GregorianCalendar;
          import java.util.
          
          public class YouTubeDurationUtils {
              /**
               * 
               * @param duration
               * @return "01:02:30"
               */
              public static String convertYouTubeDuration(String duration) {
                  String youtubeDuration = duration; //"PT1H2M30S"; // "PT1M13S";
                  Calendar c = new GregorianCalendar();
                  try {
                      DateFormat df = new SimpleDateFormat("'PT'mm'M'ss'S'");
                      Date d = df.parse(youtubeDuration);
                      c.setTime(d);
                  } catch (ParseException e) {
                      try {
                          DateFormat df = new SimpleDateFormat("'PT'hh'H'mm'M'ss'S'");
                          Date d = df.parse(youtubeDuration);
                          c.setTime(d);
                      } catch (ParseException e1) {
                          try {
                              DateFormat df = new SimpleDateFormat("'PT'ss'S'");
                              Date d = df.parse(youtubeDuration);
                              c.setTime(d);
                          } catch (ParseException e2) {
                          }
                      }
                  }
                  c.setTimeZone(TimeZone.getDefault());
          
                  String time = "";
                  if ( c.get(Calendar.HOUR) > 0 ) {
                      if ( String.valueOf(c.get(Calendar.HOUR)).length() == 1 ) {
                          time += "0" + c.get(Calendar.HOUR);
                      }
                      else {
                          time += c.get(Calendar.HOUR);
                      }
                      time += ":";
                  }
                  // test minute
                  if ( String.valueOf(c.get(Calendar.MINUTE)).length() == 1 ) {
                      time += "0" + c.get(Calendar.MINUTE);
                  }
                  else {
                      time += c.get(Calendar.MINUTE);
                  }
                  time += ":";
                  // test second
                  if ( String.valueOf(c.get(Calendar.SECOND)).length() == 1 ) {
                      time += "0" + c.get(Calendar.SECOND);
                  }
                  else {
                      time += c.get(Calendar.SECOND);
                  }
                  return time ;
              }
          }
          

          【讨论】:

            【解决方案10】:

            还有另一个很长的路要走。

            // PT1H9M24S -->  1:09:24
            // PT2H1S"   -->  2:00:01
            // PT23M2S   -->  23:02
            // PT31S     -->  0:31
            
            public String convertDuration(String duration) {
                duration = duration.substring(2);  // del. PT-symbols
                String H, M, S;
                // Get Hours:
                int indOfH = duration.indexOf("H");  // position of H-symbol
                if (indOfH > -1) {  // there is H-symbol
                    H = duration.substring(0,indOfH);      // take number for hours
                    duration = duration.substring(indOfH); // del. hours
                    duration = duration.replace("H","");   // del. H-symbol
                } else {
                    H = "";
                }
                // Get Minutes:
                int indOfM = duration.indexOf("M");  // position of M-symbol
                if (indOfM > -1) {  // there is M-symbol
                    M = duration.substring(0,indOfM);      // take number for minutes
                    duration = duration.substring(indOfM); // del. minutes
                    duration = duration.replace("M","");   // del. M-symbol
                    // If there was H-symbol and less than 10 minutes
                    // then add left "0" to the minutes
                    if (H.length() > 0 && M.length() == 1) {
                        M = "0" + M;
                    }
                } else {
                    // If there was H-symbol then set "00" for the minutes
                    // otherwise set "0"
                    if (H.length() > 0) {
                        M = "00";
                    } else {
                        M = "0";
                    }
                }
                // Get Seconds:
                int indOfS = duration.indexOf("S");  // position of S-symbol
                if (indOfS > -1) {  // there is S-symbol
                    S = duration.substring(0,indOfS);      // take number for seconds
                    duration = duration.substring(indOfS); // del. seconds
                    duration = duration.replace("S","");   // del. S-symbol
                    if (S.length() == 1) {
                        S = "0" + S;
                    }
                } else {
                    S = "00";
                }
                if (H.length() > 0) {
                    return H + ":" +  M + ":" + S;
                } else {
                    return M + ":" + S;
                }
            }
            

            【讨论】:

              【解决方案11】:

              我已经编写并使用此方法来获取实际持续时间。希望这会有所帮助。

              private String parseDuration(String duration) {
                  duration = duration.contains("PT") ? duration.replace("PT", "") : duration;
                  duration = duration.contains("S") ? duration.replace("S", "") : duration;
                  duration = duration.contains("H") ? duration.replace("H", ":") : duration;
                  duration = duration.contains("M") ? duration.replace("M", ":") : duration;
                  String[] split = duration.split(":");
                  for(int i = 0; i< split.length; i++){
                      String item = split[i];
                      split[i] = item.length() <= 1 ? "0"+item : item;
                  }
                  return TextUtils.join(":", split);
              }
              

              【讨论】:

                【解决方案12】:

                时间已经被格式化了,看来只要替换就足够了。

                 private String stringForTime(String ytFormattedTime) {
                                 return ytFormattedTime
                                        .replace("PT","")
                                        .replace("H",":")
                                        .replace("M",":")
                                        .replace("S","");
                 }
                

                【讨论】:

                  【解决方案13】:
                  public String pretty(String duration) {
                    String time = duration.replace("PT", "");
                    String hour = null;
                    String minute = null;
                    String second = null;
                  
                    if (time.indexOf("H") > 0) {
                      String[] split = time.split("H");
                      if (split.length > 0) {
                        hour = split[0];
                      }
                      if (split.length > 1) {
                        time = split[1];
                      }
                    }
                  
                    if (time.indexOf("M") > 0) {
                      String[] split = time.split("M");
                      if (split.length > 0) {
                        minute = split[0];
                      }
                      if (split.length > 1) {
                        time = split[1];
                      }
                    }
                  
                    if (time.indexOf("S") > 0) {
                      String[] split = time.split("S");
                      if (split.length > 0) {
                        second = split[0];
                      }
                    }
                  
                    if (TextUtils.isEmpty(hour)) {
                      if (TextUtils.isEmpty(minute)) { return "0:" + pad(second, 2, '0'); }
                      else { return minute + ":" + pad(second, 2, '0'); }
                    }
                    else {
                      if (TextUtils.isEmpty(minute)) { return hour + ":00:" + pad(second, 2, '0'); }
                      else {return hour + ":" + pad(minute, 2, '0') + ":" + pad(second, 2, '0');}
                    }
                  }
                  
                  private String pad(String word, int length, char ch) {
                    if (TextUtils.isEmpty(word)) { word = ""; }
                    return length > word.length() ? pad(ch + word, length, ch) : word;
                  }
                  

                  【讨论】:

                    【解决方案14】:

                    使用this 网站:

                    // URL that generated this code:
                    // http://txt2re.com/index-java.php3?s=PT1M13S&6&3&18&20&-19&-21 
                    
                    import java.util.regex.*;
                    
                    class Main
                    {
                      public static void main(String[] args)
                      {
                        String txt="PT1M13S";
                    
                        String re1="(P)";   // Any Single Character 1
                        String re2="(T)";   // Any Single Character 2
                        String re3="(\\d+)";    // Integer Number 1
                        String re4="(M)";   // Any Single Character 3
                        String re5="(\\d+)";    // Integer Number 2
                        String re6="(S)";   // Any Single Character 4
                    
                        Pattern p = Pattern.compile(re1+re2+re3+re4+re5+re6,Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
                        Matcher m = p.matcher(txt);
                        if (m.find())
                        {
                            String c1=m.group(1);
                            String c2=m.group(2);
                            String minutes=m.group(3); // Minutes are here
                            String c3=m.group(4);
                            String seconds=m.group(5); // Seconds are here
                            String c4=m.group(6);
                            System.out.print("("+c1.toString()+")"+"("+c2.toString()+")"+"("+minutes.toString()+")"+"("+c3.toString()+")"+"("+seconds.toString()+")"+"("+c4.toString()+")"+"\n");
                    
                            int totalSeconds = Integer.parseInt(minutes) * 60 + Integer.parseInt(seconds);
                        }
                      }
                    }
                    

                    【讨论】:

                    • 呃,对不起,但没有。 如果你坚持为此使用正则表达式,那么至少让它真正检查输入是否是远程格式正确的。例如,您的代码接受 00Dumdidledum1And a long story and some tex3asdf0
                    • 更好,但你可以简化很多:PT(\\d+)M\(\\d+\)S:我们只关心两个数字组,. 真的不应该使用,因为PT1H3M 也是有效的 ISO8601 ,但完全是别的意思(1 小时 + 3 分钟)。
                    • 您没有尝试解析整个格式。这只能解析 OP 的示例,并且在实际使用中会严重失败。视频的时长可以短至几秒,也可以长至几个小时。
                    【解决方案15】:

                    问题Converting ISO 8601-compliant String to java.util.Date 包含另一个解决方案:

                    更简单的解决方案可能是使用数据类型转换器 JAXB,因为 JAXB 必须能够根据 ISO8601 日期字符串解析 到 XML 模式规范。 javax.xml.bind.DatatypeConverter.parseDateTime("2010-01-01T12:00:00Z") 会给你一个Calendar 对象,如果你需要一个Date 对象,你可以简单地使用getTime()

                    【讨论】:

                    • 这个问题是关于 ISO8601 duration 格式,不是关于 ISO8601 date 格式。
                    猜你喜欢
                    • 2014-08-15
                    • 2015-08-24
                    • 1970-01-01
                    • 1970-01-01
                    • 2013-05-20
                    • 1970-01-01
                    • 2021-08-05
                    • 2013-11-02
                    • 2014-04-04
                    相关资源
                    最近更新 更多