Как конвертировать продолжительность Youtube API V3 в Java
API Youtube V3 использует формат времени ISO8601 для описания продолжительности видео. Что-то вроде "PT1M13S". И теперь я хочу преобразовать строку в количество секунд (например, 73 в этом случае).
есть ли какая-либо библиотека Java может помочь мне легко выполнить задачу под Java 6? Или я должен сделать задачу regex самостоятельно?
редактировать
наконец, я принимаю ответ от @Joachim Sauer
пример кода с Joda
в под.
PeriodFormatter formatter = ISOPeriodFormat.standard();
Period p = formatter.parsePeriod("PT1H1M13S");
Seconds s = p.toStandardSeconds();
System.out.println(s.getSeconds());
13 ответов
Джода Времени является библиотекой go-to для функций, связанных со временем любого рода.
для этого конкретного случая ISOPeriodFormat.standard () возвращает PeriodFormatter
который может анализировать и форматировать этот формат.
результирующий объект a Period
(JavaDoc). Получение фактического количества секунд будет тогда period.toStandardSeconds().getSeconds()
, но я предлагаю вам просто обрабатывать продолжительность как Period
объект (для удобства регулировать и для типа безопасности).
Edit: Примечание от будущего меня: этот ответ уже несколько лет. В 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;
}
вот мое решение
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])
Примечание: он может выбросить исключение, поэтому, пожалуйста, обращайтесь с ним в зависимости от размера результата.split (":");
вы можете использовать стандарт SimpleDateFormat
для разбора String
до 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;
}
может быть, это поможет кому-то, кто не хочет никакой библиотеки, кроме простой функции,
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;
}
я реализовал этот метод, и он работает до сих пор.
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, в java.утиль.Дата содержит другое решение:
более простое решение, возможно, использовать преобразователь типа данных в JAXB, так как JAXB должен иметь возможность анализировать строку даты ISO8601 в соответствии к спецификации схемы XML.
javax.xml.bind.DatatypeConverter.parseDateTime("2010-01-01T12:00:00Z")
даст вамCalendar
объект, и вы можете просто использоватьgetTime()
на нем, если вам нужноDate
"объект".