I am timing an event like this:
seconds = System.currentTimeMillis() / 1000;
// Something happens here
time = System.currentTimeMillis() / 1000 - seconds;
and then I have attempted to format it:
String Time = String.format("%d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes(time),
TimeUnit.MILLISECONDS.toSeconds(time) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(time)));
and the results don't make any sense, the minutes are thousands but the seconds seem to be normal numbers. What is the proper way to format the time?
long milliseconds = System.currentTimeMillis()%1000;
long seconds = (System.currentTimeMillis()/1000)%60;
long minutes = (System.currentTimeMillis()/(60*1000))%60;
long hours = (System.currentTimeMillis()/(60*60*1000));
Leave out whatever parts you don't want and remove the modulus from the highest one you do.
Related
So I've written a rather silly program just to work with nanoTime a bit. I wanted to be able to check execution times of small bits of code so I figure nanoTime would be the best. I wanted to determine the average execution time of this short bit of code, so I put it inside a for loop. However, when inside the for loop, the average drops to about 6,000 nano seconds less. I know this isn't a huge difference on small code but I am curious why it would be any different for the same exact code?
here are the two blocks that yield different times:
this one is an average of about 8064 nano seconds:
long start, end, totalTime;
double milliseconds, seconds, minutes, hours, days, years;
totalTime = 0;
start = System.nanoTime();
milliseconds = System.currentTimeMillis();
seconds = milliseconds/1000;
minutes = seconds/60;
hours = minutes/60;
days = hours/24;
years = days/365;
end = System.nanoTime();
totalTime = end-start;
and this one is an average of about 2200 nano seconds:
long start, end, totalTime;
double milliseconds, seconds, minutes, hours, days, years;
totalTime = 0;
for(int i = 1; i < 11; i++){
start = System.nanoTime();
milliseconds = System.currentTimeMillis();
seconds = milliseconds/1000;
minutes = seconds/60;
hours = minutes/60;
days = hours/24;
years = days/365;
end = System.nanoTime();
totalTime += end-start;
System.out.println(end-start); //this was added to manually calc. the average to
//make sure the code was executing properly. does not effect execution time.
}
and then to find the average you take totalTime*.1
This is exactly what you should expect from any Java program. The Java runtime, specifically the JIT compiler, will optimize code more heavily the more it gets run over the lifetime of the program. You should expect code to speed up after getting run multiple times.
I need to get the days,hours, minutes, seconds from current time till 2038.I am having issues with the output.
public class Assignment1 {
public static void main(String[] args) {
long now = System.currentTimeMillis();
long y2k38 = (long) Math.pow(2, 31)*1000;
long diffmillis = y2k38-now;
long diffsec = (y2k38-now)/1000;
long diffmin = diffsec/60;
long diffhours = diffmin/60;
long diffdays = diffhours/24;
System.out.printf(
"Y2K38 will occur in %d days.\n"+
"Y2K38 will occur in %d hours.\n"+
"Y2K38 will occur in %d minutes.\n"+
"Y2K38 will occur in %d seconds.\n",
(diffdays%24),(diffhours%60), (diffmin%60),(diffsec%60));
}
}
Your main issue is that your diffdays, diffhours, diffmin, and diffsec are all just constants that don't actually interact with the current timestamp, so y2k38-diffdays, y2k38-diffhours, and y2k38-diffmin are simply constants subtracting constants.
You will likely want to calculate the number of milliseconds until 2038 with y2k38-now, and then convert up to the units you want from there.
For example, (y2k38-now)/1000 should give you seconds until 2038, (y2k38-now)/(60*1000) should give you minutes, etc.
I have code which checks if the given "A" time (in milliseconds) is in the given "b" time period.
private static boolean isInTimeInterval(long time, int timePeriod) {
long curTime = Calendar.getInstance().getTimeInMillis();
// time period is in hours, 1 hour is 3600000 ms;
long startTime = curTime - timePeriod * 3600000;
if (time >= startTime && time < curTime){
return true;
}
return false;
}
I take the time from a file and parse it into a long like this:
(Long.parseLong(array[2]))
But it doesn't work correctly, what is wrong ?
To simplify things, I would suggest that you first subtract the start time from the end time, check to see if that is positive and then decide if the remaining milliseconds is smaller than the requested time period.
long difference = Calendar.getInstance().getTimeInMillis() - time;
long timeRange = timePeriod * 3600000;
return (0 <= difference && differance <= timeRange);
It makes the code slightly smaller in lines, but more importantly, it simplifies the math to where you know the code isn't the problem.
As far as the errors you are likely encountering, I'd look to your
Long.parseLong(array[2])
As that is likely grabbing the input in a manner you aren't expecting. For starters, I'd put in some logging or at least one-time println debugging statements to verify the input times are what I thought they were.
I am making listview with timers, each with different deadline depending on the database(similar to auction)
Time now = new Time();
now.setToNow();
now.normalize(true);
nowMillis = now.toMillis(true);
.
.
String endtime = a.get(position).get(TAG_ENDTIME);
Integer timeSecond = Integer.parseInt(endtime.substring(17, 19));
Integer timeMinute = Integer.parseInt(endtime.substring(14, 16));
Integer timeHour = Integer.parseInt(endtime.substring(11, 13));
Integer timeDay = Integer.parseInt(endtime.substring(0, 2));
Integer timeMonth = Integer.parseInt(endtime.substring(3, 5)) - 1;
Integer timeYear = Integer.parseInt(endtime.substring(6, 10));
Time future = new Time();
future.set(timeSecond, timeMinute, timeHour, timeDay, timeMonth, timeYear);
future.normalize(true);
long futureMillis = future.toMillis(true);
long interval = futureMillis - nowMillis;
new CountDownTimer(interval,1000)
{
#Override
public void onTick(long millisUntilFinished)
{
Long interval = millisUntilFinished;
int days = (int) ((millisUntilFinished / 1000) / 86400);
int hours = (int) (((millisUntilFinished / 1000) - (days * 86400)) / 3600);
int minutes = (int) (((millisUntilFinished / 1000) - (days * 86400) - (hours * 3600)) / 60);
int seconds = (int) ((millisUntilFinished / 1000) % 60);
String countdown = String.format("%dd %dh %dm %ds", days, hours, minutes, seconds);
holder.duration.setText(countdown);
}
#Override
public void onFinish()
{
// TODO Auto-generated method stub
holder.duration.setText(TimeUp);
}
}.start();
That code works almost perfectly when there is only one instance.
However the problem arise when there is several instance, around 4-5 timer running at the same time
Several/all the countdown will start to flicker, be it seconds, minutes, hours, or days.
e.g. one of my timer flicker between 27d 11h 54m 50s and 0d 23h 47m 0s
Since this occur on both on emulator and on my device, it seems to be my code's flaw, but I don't have a clue what could cause this.
I tried to change
holder.duration.setText(countdown) into holder.duration.setText(millisUntilFinished)
and the the countdown flickers between the desired duration and a huge, random number,
Please help.
You should use one TimerTask and put all your UI updates into that single timer instead running multiple CountDownTimers for essentially the same job since you're already doing all the math to determine when "time is up" for any particular item, you might just run one TimerTask and once a second have it update everything. CountDownTimer is useful for a single implementation count down because it does some built-in math, etc. You're redoing all that math, so you might as well use one instance of a regular TimerTask.
The implementation of CountDownTimer relays on scheduled delays in Handler messaging. A single countdown instance is unlikely to result in any bizarre behavior, but if you have several going that all supposed to "tick" when the system clock hits each second (the time in millis ends in "000" - once a second, and all at the same time), then those handlers will all try to fire simultaneously and inevitably fail.
If the UI or other process will likely delay some of these messages, even to the point where it will "skip ticks" to catch up. Also, that means that the next message delay could be only milliseconds from the next tick (i.e. if it's supposed to check every 1000 millis, but is delayed an additional 1990 millis, then it will skip a tick and also schedule the next message for 10 millis into the future.
I'm wanting to have my JLabel display values in the format of HH:mm:ss without making use of any external libraries. (the label will update every second)
So for example, the following input in seconds and the desired output are below:
Seconds: Output:
--------------------------------------------------
long seconds = 0 00:00:00
long seconds = 5 00:00:05
long seconds = 500 00:08:20
long seconds = 5000 01:23:20
Note: the seconds value is of type long
I'm aware that typically one would just do the following conversions to get the desired numbers:
long s = 5000; //total seconds
long hrs = (s / 3600) //hours
long mins = ((s%3600)/60) //minutes
long secs = (s%60) //seconds
However, this leaves decimals on the values. Perhaps there is some sort of formatting that will allow me to toss the un-needed decimals.
Options I have come across were String.format(), SimpleDateFormat(), or concatenating a string myself.
The thing is, I will be updating this JLabel every second and sometimes it can count to the equivalent of 5-6 days if not longer.
So I'm looking for someone who has more experience in the area than I, and knows the most efficient way to tackle this issue.
I would use SimpleDateFormat if I were you.
If SDF is too slow for you, profile all your options and pick the fastest one, then refactor the rest of your code until it's fast enough.
Remember that premature optimization is the root of all evil, and that you should only really do any optimizing after you've profiled your code and missed your target execution time.
SimpleDateFormat() is really quite appropriate for your needs.
Use the TimeUnit class, as shown here in combination with the javax.swing.Timer class set to execute at 1 second intervals.
If you don't mind values wrapping then use SimpleDateFormat as follows. Remember x1000 to convert to milliseconds and to manually override the timezone.
long value = 5 * 24 * 3600 + 5000;
// wrapping solution
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
// ensure no daylight saving +1 hour
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(sdf.format(value * 1000));
Output
01:23:20
If you want the hours to go past 23.59.59 then this is the simplest I could come up with. I used DecimalFormat to force at least 2 digits for the hours.
long value = 5 * 24 * 3600 + 5000;
long hours = value / 3600; // whole hours
long mins = value / 60 - hours * 60;
long secs = value % 60;
System.out.println(String.format("%s:%2d:%2d",
new DecimalFormat("00").format(hours), mins, secs));
Output
121:23:20
I've found this to be extremely fast. Try it out. Seconds go from 0 - 59, minutes go from 0 - 59, hours go from 0 - 2,562,047,788,015. Afterwards the hours become negative and begin going towards that maximum.
performing the "+" operator on Strings is very slow. A StringBuilder performs grouping strings together the fastest from what I've seen. You should also be using "chars" not "String/Byte" Bytes are very slow as well. I'd prefer doing only multiplication however dividing by 36 and 6 give decimals that are to large for holding.
StringBuilder sb = new StringBuilder(8);
long hours = time / 3600000;
long minutes = (time - hours * 3600000) / 60000;
long seconds = (time - hours * 3600000 - minutes * 60000) / 1000;
if (hours < 10)
sb.append('0');
sb.append(hours);
sb.append(':');
if (minutes < 10)
sb.append('0');
sb.append(minutes);
sb.append(':');
if (seconds < 10)
sb.append('0');
sb.append(seconds);
String formattedTime = sb.toString();
.....
If you don't want to use a formatter class, you can get your work done by using basic operations like conversion among wrapper classes and String operations. Take a look at this code:
long h, m, s; // Initialize them after calculation.
String h1, m1, s1;
h1 = Long.toString( h );
m1 = Long.toString( m );
s1 = Long.toString( s );
if ( s1.length() < 2 )
s1 = "0" + s1;
if ( m1.length() < 2 )
m1 = "0" + m1;
if ( h1.length() < 2 )
h1 = "0" + h1;
String output = h1+":"+m1+":"+s1;
Supposing you have correctly calculated values of seconds, minutes and hours, you can gather String versions of these variables, then format them with a simple length check and finally concatenate these time unit parts.
i think you want to do the math you indicated, but take the floor of each value. then concatenate..
public class Test{
public static void main(String args[]){
double d = -100.675;
float f = -90;
System.out.println(Math.floor(d));
System.out.println(Math.floor(f));
System.out.println(Math.ceil(d));
System.out.println(Math.ceil(f));
}
}