I have a mp3 file and my application must seek to some selected time of that mp3 file then start playing from there.
I convert my string time by this method to int value
private static int convert(String time) {
int quoteInd = time.indexOf(":");
int pointInd = time.indexOf(".");
int min = Integer.valueOf(time.substring(0, quoteInd));
int sec = Integer.valueOf(time.substring(++quoteInd, pointInd));
int mil = Integer.valueOf(time.substring(++pointInd, time.length()));
return (((min * 60) + sec) * 1000) + mil;
}
Note: my stings is like this 5:12.201 that means 5 mins and 12 seconds and 201 milliseconds.
I getted these times from MP3 Audio Editor application (it's for windows) and I checked theme with KMPlayer application (it's for windows). And these times was correct on both of them.
But in my app when I seek my MediaPlayer to that time, audio doesn't start from my selected position. (time is correct but sound is different.)
I thought that the MediaPlayer doesn't seek to that time correctly. So I checked current position by calling getCurrentPosition() before playing but returned value and seeked value was same.
I haven't any Idea about It.
Edit:
My problem is NOT time converting.
I convert and seek to there correctly but it play something that not expected in that time.
It means timing in KMPlayer and Android are differents.
My question is Way? and How can is solve it?
You must seek using the seekTo method. This expects miliseconds as time offset. Your offset is how far from the beginning you want to play, for example 1 minute from start can be your offset.
Note: my strings is like this 5:12.201 (Mins : Secs : Millisecs)
If you want to seek to a time like 5:12.201 then use seekTo(312201);
Explained :
1000 ms gives you one second, so 12000 is 12 seconds, and 60000 is one minute.
If you want 5m:12s time then do as :
MyMins = 1000 * 60 * 5; //# 5 mins at 60 secs per minute
MySecs = 1000 * 12; //# 12 secs
MyMilliSecs = 201; //# 201 millisecs
SeekValue = (MyMins + MySecs + MyMilliSecs);
seekTo(SeekValue); //# seeks to 312201 millisecs (is == 5 min & 12 secs & 201 ms)
I usually use this function.
I think It can help to you.
public static String milliSecondsToTimer(long milliseconds){
String finalTimerString = "";
String secondsString = "";
int hours = (int)( milliseconds / (1000*60*60));
int minutes = (int)(milliseconds % (1000*60*60)) / (1000*60);
int seconds = (int) ((milliseconds % (1000*60*60)) % (1000*60) / 1000);
if(hours > 0){
finalTimerString = hours + ":";
}
if(seconds < 10){
secondsString = "0" + seconds;
}else{
secondsString = "" + seconds;}
finalTimerString = finalTimerString + minutes + ":" + secondsString;
return finalTimerString;
}
Good luck :)
Related
I am trying to get the difference of two dates and get the results in minutes. i have the two dates in milliseconds
long start = 1447143052593L;
long end = 1447146592540L;
output of above is
I/System.out﹕ 03:10:52
I/System.out﹕ 04:09:52
what i expect to be 0:59
And i tried to get the difference in the below way, it does not work.
long mills = end - start;
long Hours = mills/(1000 * 60 * 60);
long Mins = mills % (1000*60*60);
String diff= Hours + ":" + Mins;
And the when i print the String diff i get the result as below
I/System.out﹕ 0:3539947
try this approach:
long Hours = mills / (1000 * 60 * 60);
long Mins = (mills - Hours * (1000 * 60 * 60)) / (1000 * 60);
You are on the correct way, but your Mins now has the milliseconds that are remaining after the hours, instead of the minutes that are remaining.
This should work:
long Mins = (mills % (1000*60*60)) / (1000*60); //make it minutes
Usually you just need to make a Date object
Date startDate = new Date(start);
Date endDate = new Date(end);
int startminutes = startDate.getMinutes();
int endminutes = endDate.getMinutes();
And i say usually because it looks like it has been deprecated some time ago (while i hope it should be still working).
Looks like now they want we to use the Calendar class for this.
Hope this helps.
I am using a Date and Time Dialog to get a Date and Time for an Event Specifed by the User. That data is the Converted by doing the following:
int yearE = Integer.valueOf(evntDate.split("/")[2]);
int monthE = Integer.valueOf(evntDate.split("/")[1]);
int dayE = Integer.valueOf(evntDate.split("/")[0]);
int hour = Integer.valueOf(evntTm.split(":")[0]);
int min = Integer.valueOf(evntTm.split(":")[1]);
With the Values of:
eventDate = "3/5/2015";
eventTime = "13:2";
I then get that data and COnvert it into Milliseconds and Store that in the Database:
newCalendar.set(yearE, monthE, dayE,hour, min, 0);
startTime = newCalendar.getTimeInMillis();
...
When I load the Info from the Database, I try to calculate the amount of time left until the Specified date. So I do the following:
Long timeL = Long.valueOf(time);
Calendar eventDay = Calendar.getInstance();
eventDay.setTimeInMillis(timeL);
Calendar today = Calendar.getInstance();
long diff = eventDay.getTimeInMillis() - today.getTimeInMillis();
// CONVERT:
int seconds = (int) TimeUnit.MILLISECONDS.toSeconds(diff);
int minutes = (int) TimeUnit.MILLISECONDS.toMinutes(diff);
int hours = (int) TimeUnit.MILLISECONDS.toHours(diff);
int days = (int) TimeUnit.MILLISECONDS.toDays(diff);
...
When I log the above data, the days are usually around 30-32 and the rest of the data is incorrect as well. What am I doing wrong? Or what are some alternatives?
Consider using the Joda time library instead of Calendar, it's much easier to work with.
As you're on android, I'll assume that you're using gradle, so go ahead and drop this in your dependencies
compile 'joda-time:joda-time:2.3'
I've created a small psvm to demo how you can use it
import org.joda.time.DateTime;
import org.joda.time.Period;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.PeriodFormat;
import static java.lang.String.format;
public class DateTimeDemo {
public static void main(String[] args) {
// Your date/time values, I'll assume you missed a digit off the time ;)
String eventDate = "3/5/2015";
String eventTime = "13:20";
// convert these to a DateTime object
DateTime targetDateTime = DateTime.parse(format("%s %s", eventDate, eventTime), DateTimeFormat.forPattern("dd/MM/yyyy HH:mm"));
// print out the millis, or in your case, save it to DB
System.out.println("targetDateTime in millis is " + targetDateTime.getMillis());
// grab a timestamp
DateTime now = DateTime.now();
// print it out, just for demo
System.out.println("millis for now is " + now.getMillis());
// create a period object between the two
Period period = new Period(now, targetDateTime);
// print out each part
System.out.println("seconds " + period.getSeconds());
System.out.println("hours " + period.getHours());
System.out.println("months " + period.getMonths());
// convert the period to a printable String
String prettyPeriod = PeriodFormat.getDefault().print(period);
// write it out!
System.out.println(prettyPeriod);
}
}
Output is
targetDateTime in millis is 1430623200000
millis for now is 1425527593584
seconds 46
hours 22
months 1
1 month, 3 weeks, 6 days, 22 hours, 26 minutes, 46 seconds and 416 milliseconds
You can use Joda for that.
long dbTime = 1425525415837L;
Period period = new Period( dbTime, System.currentTimeMillis() );
String formatted = PeriodFormat.getDefault().print(period);
System.out.println( formatted );
If you want more control of the format use PeriodFormatter.
If you want to get the seconds, minutes, hours, etc. and not just print them, you can use the various available methods. For example:
period.getSeconds();
period.getHours();
period.getMonths();
More formatting options are described in this question.
Are you expecting to see something similar:
seconds = 36 (always less than 60)
minutes = 12 (always less that 60)
hours = 17 (always less than 24)
days = 45 (always less that 31 if # of months is used, else < 366 if # of years is used)
...
...
from:
// CONVERT:
int seconds = (int) TimeUnit.MILLISECONDS.toSeconds(diff);
int minutes = (int) TimeUnit.MILLISECONDS.toMinutes(diff);
int hours = (int) TimeUnit.MILLISECONDS.toHours(diff);
int days = (int) TimeUnit.MILLISECONDS.toDays(diff);
Its a logical error then. TimeUnit.MILLISECONDS.toXXXX(long) converts the whole time-difference into the specified units. This is of no value to you.
As an example, say you set the event's date to 32 days from now - and time to 13:15.
Millisecond difference =
2764800000 (32 days in millis)
+ 46800000 (13 hours in millis)
+ 900000 (15 minutes in millis)
= 2812500000
Using this time-difference, the following log:
int seconds = (int) TimeUnit.MILLISECONDS.toSeconds(diff);
int minutes = (int) TimeUnit.MILLISECONDS.toMinutes(diff);
int hours = (int) TimeUnit.MILLISECONDS.toHours(diff);
int days = (int) TimeUnit.MILLISECONDS.toDays(diff);
produces:
Seconds left: 2812500
Minutes left: 46875
Hours left: 781
Days left: 32
These figures are not off. A quick check would be: time difference in millis was: 2812500000 => in seconds would be diff/1000 = 2812500 => in minutes would be => diff/1000/60 = 46875 and so on.
Relative time:
To get relative time such as 32 days, 13 hours and 15 minutes left, you will have to do the heavy-lifting yourself. As an example:
// I will use the actual values instead of defined
// variables to make this easier to follow
long timeDiff = 2812500000L;
// Simple division // we don't care about the remainder
// Result: 32
int days = 2812500000 / DateUtils.DAY_IN_MILLIS;
// This is what's left over after we take the days out.
// We'll use this to get the number of hours.
// Result: 47700000
long remainderFromDays = 2812500000 % DateUtils.DAY_IN_MILLIS;
// Simple division // we don't care about the remainder
// Result: 13
int hours = 47700000 / DateUtils.HOUR_IN_MILLIS;
// This is what's left over after we take the hours out.
// We'll use this to get the number of minutes.
// Result: 900000
long remainderFromHours = 47700000 % DateUtils.HOUR_IN_MILLIS;
// Result: 15
int minutes = 900000 / DateUtils.MINUTE_IN_MILLIS;
// Result: 0
long remainderFromMinutes = 900000 % DateUtils.MINUTE_IN_MILLIS;
// Result: 0
int seconds = 0 / 1000; // 1000 ms = 1 sec
Log.i("Time-Difference", "Event in: " + String.format("Event in %d days, %d hours, %d minutes and %d seconds", days, hours, minutes, seconds));
Output:
Event in: 32 days, 13 hours, 15 minutes and 0 seconds
This is the very reason everyone here is suggesting Joda Time. The computation above is just off the top of my head. I cannot guarantee its correctness. If you also need relative month difference (such as 3 months, 2 days ....), a lot of work will be required. There isn't a DateUtils.MONTH_IN_MILLIS constant - varying number of days - 28, 29, 30, 31.
On the other hand, Joda Time is a tried & tested product. But, if all you need is one kind of computation, used scarcely (if ever), I'd say spend some time and come up with your own implementation rather than under-employ Joda Time.
Your code looks fine to me for what you are doing. Using org.joda.time as others have suggested is a best-practice, but it won't fix the problem. Instead you need to do two things:
Verify the Month that the user entered is in range (they may have entered the date in MM/DD/YYYY format). Month values greater than 12 won't throw an exception and your diff will be way off.
The line where you construct your date, subtract 1 from the month since months should be from 0 to 11, like:
newCalendar.set(yearE, monthE-1, dayE,hour, min, 0);
I know here is lot of question on "start/stop timer".But i am looking for format of
timer. I am developing one recording application which show record time.
I able to show time in second format like 1 2 3 4 5. but i need to show this time like
00.01. I need some hint or reference. here is image which i need to show.
Thanks in Advance
Here is the very nice tutorial of simple countdown timer. Go through it and you will be able to achieve what you want.
Or A Stitch in Time is the efficient way to implement the stop watch type app from developer.android.com and yes it uses the format you required.
You can try this:
private String stringForTime(int timeMs) {
StringBuilder mFormatBuilder = new StringBuilder();
Formatter mFormatter = new Formatter(mFormatBuilder, Locale.getDefault());
int totalSeconds = timeMs / 1000;
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = totalSeconds / 3600;
mFormatBuilder.setLength(0);
if (hours > 0) {
return mFormatter.format("%d:%02d:%02d", hours, minutes, seconds).toString();
} else {
return mFormatter.format("%02d:%02d", minutes, seconds).toString();
}
}
I'm implementing something which will display the ETA and I need some help with displaying this correctly.
Example
//calculates the ETA in hours
var eta = CalculateEta(currentLocation, destination); //returns eq. 0,2169067
How can I display this in minutes and if the ETA is greather then 1 in hours and minutes?
Example
If my returned ETA value equals 0,2169067 I would like to display it like this:
"Estimated Time Of Arrival is in 21 minutes"
If my ETA has a value of 1,502235 I would like to display:
"Estimated Time Of Arrival is in 1 hour and 50 minutes"
Hope this makes it more clear.
private static String viaDate(float eta) {
DateFormat format = new SimpleDateFormat("H 'hours,' m 'minutes,' s 'seconds,' S 'ms'", Locale.US);
// convert to milliseconds, for some reason substract one hour, 0f results in 1:00
Date date = new Date((long) (eta * ONE_HOUR) - ONE_HOUR);
return format.format(date);
}
private static String manual(float eta) {
int hour = (int) eta;
eta = (eta - hour) * 60;
int minutes = (int) eta;
eta = (eta - minutes) * 60;
int seconds = (int) eta;
eta = (eta - seconds) * 1000;
int ms = (int) eta;
return String.format("%d hours, %d minutes, %d seconds, %d ms", hour, minutes, seconds, ms);
}
Both will result in something like
"0 hours, 14 minutes, 2 seconds, 400 ms"
If you don't want to display hours only when > 0 and display "hours" instead of "hour" when > 1 then take the manual version add some if (hour > 0) { /* add "x hours" */ } logic
That might work with SimpleDateFormat as well but I was too lazy to look up what formatting options you have.
i want to run an countdown time , in which i want to show days,hours,sec and milisec remaining for a specific date. and will be be keep changing till the end of the specific date.
Hope you can understand.
Thanks in advance.
Well, I think the problem is, that you dont know, how to work with the time. Here i have a method I use to calculate the amount of time of some items which I parse out of a db.
The param is a double value, which has got the whole time in seconds. It returns a string with the time in days, hours, minutes and seconds as string.
public String timeCalculate(double ttime) {
long days, hours, minutes, seconds;
String daysT = "", restT = "";
days = (Math.round(ttime) / 86400);
hours = (Math.round(ttime) / 3600) - (days * 24);
minutes = (Math.round(ttime) / 60) - (days * 1440) - (hours * 60);
seconds = Math.round(ttime) % 60;
if(days==1) daysT = String.format("%d day ", days);
if(days>1) daysT = String.format("%d days ", days);
restT = String.format("%02d:%02d:%02d", hours, minutes, seconds);
return daysT + restT;
}
For the countdown itself...take the target timestamp minus the actual one and voila, you've got seconds left :) Put those seconds to this method and you've got the remaining time. Now you just need to do some UI things ;)
Oh, and for the usual Unix Timestamp you can use this little method:
public static long getTimestamp() {
return System.currentTimeMillis() / 1000;
}