Reputation: 1838
The Youtube V3 API uses ISO8601 time format to describe the duration of videos. Something likes "PT1M13S". And now I want to convert the string to the number of seconds (for example 73 in this case).
Is there any Java library can help me easily do the task under Java 6? Or I have to do the regex task by myself?
Edit
Finally I accept the answer from @Joachim Sauer
The sample code with Joda
is as below.
PeriodFormatter formatter = ISOPeriodFormat.standard();
Period p = formatter.parsePeriod("PT1H1M13S");
Seconds s = p.toStandardSeconds();
System.out.println(s.getSeconds());
Upvotes: 21
Views: 8972
Reputation: 3798
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;
}
Upvotes: 0
Reputation: 1160
Time is already formatted, so it seems just replacing will be enough.
private String stringForTime(String ytFormattedTime) {
return ytFormattedTime
.replace("PT","")
.replace("H",":")
.replace("M",":")
.replace("S","");
}
Upvotes: 0
Reputation: 308031
Joda Time is the go-to library for time-related functions of any kind.
For this specific case ISOPeriodFormat.standard() returns a PeriodFormatter
that can parse and format that format.
The resulting object is a Period
(JavaDoc). Getting the actual number of seconds would then be period.toStandardSeconds().getSeconds()
, but I suggest you just handle the duration as a Period
object (for ease of handling and for type safety).
Edit: a note from future me: this answer is several years old now. Java 8 brought java.time.Duration
along which can also parse this format and doesn't require an external library.
Upvotes: 15
Reputation: 7275
I have written and used this method to get the actual duration. Hope this helps.
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);
}
Upvotes: 0
Reputation: 1078
Here is my 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);
}
}
It will return a string in H:MM:SS format if you want to convert in seconds you can use
int timeInSedonds = int timeInSecond = Integer.parseInt(arr[0])*3600 + Integer.parseInt(arr[1])*60 +Integer.parseInt(arr[2])
Note: it can throw exception so please handle it based on size of result.split(":");
Upvotes: 3
Reputation: 795
And yet another long way to do the same.
// 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;
}
}
Upvotes: 0
Reputation: 131
I may be late for the party, it's actually very simple. Although there may be better ways of doing this. duration is in milliseconds.
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;
}
Upvotes: 13
Reputation: 4411
I did by myself
Let's try
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 ;
}
}
Upvotes: 0
Reputation: 1
I've implemented this method and it has worked so far.
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;
}
Upvotes: 0
Reputation: 2002
May be this would help some one who don't want any library but a simple function,
String duration="PT1H11M14S";
This is the 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;
}
Upvotes: 1
Reputation: 303
In case you can be pretty sure about the validity of the input and can't use regex, I use this code (returns in miliseconds):
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;
}
Upvotes: 0
Reputation: 2296
The question Converting ISO 8601-compliant String to java.util.Date contains another solution:
The easier solution is possibly to use the data type converter in JAXB, since JAXB must be able to parse ISO8601 date string according to the XML Schema specification.
javax.xml.bind.DatatypeConverter.parseDateTime("2010-01-01T12:00:00Z")
will give you aCalendar
object and you can simply usegetTime()
on it, if you need aDate
object.
Upvotes: -1
Reputation: 3090
You can use the standart SimpleDateFormat
to parse the String
to a Date
and process it from there:
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));
Upvotes: 0
Reputation: 1845
Using this website:
// 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);
}
}
}
Upvotes: -1