如何在Java中转换Youtube API V3持续时间

Youtube V3 API使用ISO8601时间格式来描述video的持续时间。 有点像“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()); 

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

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

结果对象是Period ( JavaDoc )。 获得实际秒数将是period.toStandardSeconds().getSeconds() ,但我建议您只将句柄作为Period对象处理(为了便于处理和类型安全)。

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

我可能会迟到,这实际上非常简单。 虽然可能有更好的方法来做到这一点。 持续时间以毫秒为单位。

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

Java 8中的解决方案:

 Duration.parse(duration).getSeconds() 

这是我的解决方案

 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]) 

注意:它可以抛出exception,所以请根据result.split(“:”)的大小来处理它。

您可以使用标准的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)); 

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

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

可能这会帮助一些不想要任何库但只需要简单function的人,

 String duration="PT1H11M14S"; 

这是function,

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

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

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

我自己做了

我们试试吧

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

而另一个很长的路要做同样的事情。

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

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

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

使用本网站:

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

将ISO 8601兼容的String转换为java.util.Date的问题包含另一个解决方案:

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