2013-05-29 86 views
16

Youtube V3 API使用ISO8601時間格式來描述視頻的持續時間。 有點像「PT1M13S」。現在我想將字符串轉換爲秒數(例如在這種情況下爲73)。如何轉換Java中的Youtube API V3持續時間

有沒有什麼Java庫可以幫我輕鬆完成Java 6下的任務? 或者我必須自己做正則表達式任務嗎?

編輯

最後我接受@Joachim紹爾

答案與Joda的示例代碼如下所示。

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

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

重複嗎?這個問題是針對日期格式的。 – Willy

+0

真的不明白如何在這種情況下使用SimpleDateFormat獲取秒數,因爲它不是日期格式。謝謝! – Willy

+0

@nhahtdh:這不是重複的,因爲鏈接到的人處理日期字符串,而這是一個持續時間字符串! –

回答

13

Joda Time是任何類型的時間相關函數的前往庫。

對於這種特定情況,ISOPeriodFormat.standard()返回PeriodFormatter,可以解析和格式化該格式。

生成的對象是a PeriodJavaDoc)。獲得實際的秒數將是period.toStandardSeconds().getSeconds(),但我建議你只需將持續時間作爲Period對象(便於處理和類型安全)。

+0

謝謝!我先看看 – Willy

-1

使用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); 
    } 
    } 
} 
+1

呃,對不起,但沒有。 *如果*你堅持使用正則表達式來實現這一點,那麼至少使它成爲一個實際*檢查*如果輸入甚至是遠程格式良好。例如你的代碼接受'00'以及'Dumdidledum1並且一個長故事和一些tex3asdf0'。 –

+0

@Joachim:更正。請參閱編輯。 –

+0

更好,但是你可以簡化很多:'PT(\\ d +)M \(\\ d + \)S':我們只關心兩個數字組,'''真的不應該使用, PT1H3M'也是有效的ISO8601,但意思是完全不同(1小時+ 3分鐘)。 –

0

您可以使用非標準SimpleDateFormat解析StringDate,並從那裏對其進行處理:

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)); 
+0

警告:持續時間不是一個日期,並將它當作一個日期打開一大堆蠕蟲(想想閏年,閏秒,時區,...)。 –

+0

我同意,但仍然是爲了獲得定義格式的秒數這個簡單的任務,它工作得很好。 – kpentchev

+1

除格式可能包含小時,並且不一定包含分鐘(根據ISO8601,「PT10S」和「PT1H1M1S」將是有效的)。 –

-1

問題Converting ISO 8601-compliant String to java.util.Date包含了另一個解決方案:

更簡單解決方案可能會使用JAXB中的數據類型轉換器 ,因爲JAXB必須能夠根據XML Schema規範將ISO8601日期字符串解析爲 。 javax.xml.bind.DatatypeConverter.parseDateTime("2010-01-01T12:00:00Z") 會給你一個Calendar對象,如果你需要一個Date對象,你可以簡單地使用getTime()

+0

這個問題是關於ISO8601 * duration *格式和** not **關於ISO8601 * date *格式。 –

0

在情況下,你可以相當肯定對輸入的有效性,並且不能使用正則表達式,我用這個代碼(以毫秒爲單位的回報):在Java中8

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

解決方案:

Duration.parse(duration).getSeconds() 
+0

您必須確保您的JAVA_HOME設置爲JDK8,或者您的IDE配置爲使用JDK8。我不得不添加Maven插件,以使我的IntelliJ IDEA 17上面的代碼工作。插件URL:http://mvnrepository.com/artifact/org.apache.maven.plugins/maven-compiler-plugin – realPK

0

可能,這將幫助一些人不希望任何庫,但一個簡單的功能誰,

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

我實現了這個方法,它迄今工作。

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; 

} 
0

我做我自己

讓我們嘗試

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

可能是我黨後期,它實際上是非常簡單的。雖然可能有更好的方法來做到這一點。持續時間以毫秒爲單位。

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

就像地獄一樣簡單。 –

+0

太棒了!我的問題解決了。 – Hassan

0

還有另一個很長的路要做同樣的事情。

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

這裏是我的解決方案

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(「:」)的大小來處理它。

+0

這個問題的最簡單和最佳的解決方案在stackoverflow –

+0

請注意,這將是準確的時間缺少H,M或S(例如PT35M10S或PT1H30S)。 H,M或S不能保證在現場出現 –

相關問題