Comment convertir la durée V3 de L'API Youtube en Java
L'API Youtube V3 utilise le format ISO8601 time pour décrire la durée des vidéos. Quelque chose comme "PT1M13S". Et maintenant, je veux convertir la chaîne en un nombre de secondes (par exemple 73 dans ce cas).
y a-t-il une bibliothèque Java qui puisse m'aider à effectuer facilement la tâche sous Java 6? Ou je dois faire la tâche regex moi-même?
Modifier
le code échantillon avec Joda
est comme dessous.
PeriodFormatter formatter = ISOPeriodFormat.standard();
Period p = formatter.parsePeriod("PT1H1M13S");
Seconds s = p.toStandardSeconds();
System.out.println(s.getSeconds());
13 réponses
Joda Time est aller à la bibliothèque pour l'heure, les fonctions liées d'aucune sorte.
Pour ce cas précis Isopériodformat.standard () retourne un PeriodFormatter
qui peuvent analyser et formater ce format.
L'objet résultant est Period
( JavaDoc). Obtenir le nombre de secondes serait alors period.toStandardSeconds().getSeconds()
, mais je vous suggère de gérer la durée comme un Period
objet (pour faciliter la manipulation) et pour la sécurité du type).
Edit: une note du futur moi: cette réponse a plusieurs années maintenant. Java 8 a apporté java.time.Duration
le long qui peut aussi analyser ce format et n'a pas besoin d'une bibliothèque externe.
je suis peut être en retard pour la fête, c'est en fait très simple. Bien qu'il peut y avoir de meilleures façons de le faire. la durée est exprimée en millisecondes.
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;
}
Voici ma solution
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);
}
}
il retournera une chaîne au format H:MM: SS si vous voulez convertir en secondes vous pouvez utiliser
int timeInSedonds = int timeInSecond = Integer.parseInt(arr[0])*3600 + Integer.parseInt(arr[1])*60 +Integer.parseInt(arr[2])
Note: il peut jeter l'exception donc s'il vous plaît le manipuler en fonction de la taille du résultat.split (":");
Vous pouvez utiliser le standart SimpleDateFormat
pour analyser l' String
Date
et le processus à partir de là:
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));
Dans le cas où vous pouvez être assez sûr de la validité de la saisie et ne peut pas utiliser les regex, j'utilise ce code (retours en millisecondes):
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;
}
String duration="PT1H11M14S";
C'est la fonction
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;
}
j'ai mis en œuvre cette méthode et elle a fonctionné jusqu'à présent.
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;
}
je l'ai fait par moi-même
essayons
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 ;
}
}
Et encore un long chemin à faire de même.
// 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;
}
}
j'ai écrit et utilisé cette méthode pour obtenir la durée réelle. Espérons que cette aide.
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);
}
}
}
la question conversion de la chaîne conforme à la norme ISO 8601 en Java.util.Date contient une autre solution:
la solution la plus simple est peut-être d'utiliser le convertisseur de type de données JAXB, puisque JAXB doit pouvoir analyser la chaîne de date ISO8601 selon à la spécification de schéma XML.
javax.xml.bind.DatatypeConverter.parseDateTime("2010-01-01T12:00:00Z")
vous donnera unCalendar
objet et vous pouvez simplement utilisergetTime()
sur ce, si vous avez besoin d'unDate
objet.