long startTime = System.nanoTime();
long startTimer = System.currentTimeMillis();
M = app.decriptare_simpla(C);
long endTime = System.nanoTime();
long stopTimer = System.currentTimeMillis();
//mesajul initial dupa decriptare
System.out.println("M : " + M.toString());
System.out.println("Decriptarea a durat: " + (endTime - startTime));
System.out.println("Decriptarea a durat: " + (stopTimer - startTimer));
This gave me:
Decriptarea a durat: 14811776
Decriptarea a durat: 15
What I want to ask is how much of a second are those 2 numbers? I mean are they, 0.15, 0.015, 0.0015...? I'd like to print them in that manner, not as an long but don't know how many decimals to add. Same question for the other number.
The conversions follow the usual rules for Standard SI Units:
long nanoSeconds = ...
double microSeconds = nanoSeconds / 1e3;
double milliSeconds = microSeconds / 1e3;
double seconds = milliSeconds / 1e3;
// Shortcuts:
double milliSeconds = nanoSeconds / 1e6;
double sconds = nanoSeconds / 1e9;
For some conversions, you can also have a look at the TimeUnit class: It allows conversions between values in different time units, for example
long microSeconds = NANOSECONDS.toMicros(nanoSeconds);
However, it unfortunately does not allow time spans given in double precision, but only as long values.
An aside, also mentioned in the comments: Measuring time spans in the order of 10-15ms usually makes no sense due to the limited resolution of the internal timer.
Have you tried like this
System.out.println(TimeUnit.SECONDS.convert((endTime - startTime), TimeUnit.NANOSECONDS));
System.out.println(TimeUnit.SECONDS.convert((stopTimer - startTimer), TimeUnit.MILLISECONDS));
Related
I am trying to time how long something takes and i cant get it to spit out the seconds without rounding. Here is what ive tried:
long beginTime = System.nanoTime();
//Do something
long endTime = System.nanoTime();
double time = (endTime-beginTime)/1000000000;
I've also tried using the function TimeUnit.NANOSECONDS.toSeconds and that rounds the number as well.
It should give me 1.45 seconds but it gives me 1 and it should be 1445.7191 Milliseconds but it gives me 1446.
the result of your divison is implicitly casted to int, change your divisor to a double value (add a 'd' at the end): 1000000000d
long beginTime = System.nanoTime();
// Do something
long endTime = System.nanoTime();
double time = (endTime - beginTime) / 1000000000d;
System.out.println(time);
I am trying to calculate the time consumed by the program. But what is the difference between the two methods displayed below?
System.currentTimeMillis() % 1000
System.currentTimeMillis() / 1000
I assume by the fact that you're dividing by 1000 you want it in seconds?
Regardless, the modulus operator % is not what you want here, it gives you the remainder of the division by the second operand.
To get the runtime of some code, get the current time before execution, and after execution. The runtime will the the difference between the two.
System timeBefore = System.currentTimeMillis();
//PUT CODE HERE
System timeAfter = System.currentTimeMillis();
System timeDelta = timeAfter = timeBefore;
System.out.println("Runtime was " + timeDelta + " millis"); //display milliseconds
System.out.println("Runtime was " + (timeDelta / 1000) + " seconds"); //display seconds
You may want to try something like this:
public static void main(String[] args) throws InterruptedException{
long t1 = System.nanoTime();
Thread.sleep(3000L);//do your work here
long t2 = System.nanoTime();
long result = t2 - t1;
result = result / 1000000000;
System.out.println(result);
}
This will give you time in seconds...
Output:
3
Explanation of the two methods
System.currentTimeMillis() / 1000
/ is the division operator. It will return you the result of System.currentTimeMillis() divided by 1000. This is often used to convert miliseconds to seconds.
System.currentTimeMillis() % 1000
% is the remainder operator.
It will return the remainder that is left after the division by 1000 (modulus).
Oracle provides a full list of Java-Operators.
Example for the question from the title
If you want to get the total uptime off your application, you can easily receive it from the Java Runtime:
ManagementFactory.getRuntimeMXBean().getUptime()
This will return the runtime of your programm in milliseconds. By dividing it with 1000 you will get the seconds your programm is running.
Advantage:
You don't have to handle the time measurement yourself
in my run method of a game loop I tried to print the time the program has been running in java. I simply tried System.out.println(System.nanoTime() / 1000000); because that's how many milliseconds are in a second.(if you didn't know) It prints the seconds near the end but I wanted exact seconds for testing purposes. I searched online and someone suggested using the same formula I thought of. Can anyone give an exact one?
Store previous time in a private member.
private long previousTime;
Initialize it in the constructor.
previousTime = System.currentTimeMillis();
Compare it with current time in run method (each iteration of game loop)
long currentTime = System.currentTimeMillis();
double elapsedTime = (currentTime - previousTime) / 1000.0;
System.out.println("Time in seconds : " + elapsedTime);
previousTime = currentTime;
In addition to the other answers provided, you could use a standard library StopWatch, like the one provided by Google's Guava API:
Stopwatch stopwatch = new Stopwatch();
stopwatch.start();
calculate();
stopwatch.stop(); // optional
long Seconds= stopwatch.elapsedMillis() / 1000000; // equals 1 second
You can use System.currentTimeMillis to get the current time in milliseconds.
If you pick this value at the start of your application and at the end, the subtraction of both values will give you the time your application was running.
final long start = System.currentTimeMillis();
// your code here...
final long end = System.currentTimeMillis();
System.out.println("The program was running: " + (end-start) + "ms.");
If you want it in seconds, just divide it with 1000 like you mentioned.
System.out.println("The program was running: " + ((double)(end-start)/1000.0d) + "ms.");
How to generate a random value bigger than value of System.currentTimeInMillis(). I use Random object.how can I obtain a value that have min range as System.currentTimeInMillis()?
Doesn't
long value = System.currentTimeMillis() + (long)random.nextInt(range);
work?
If you want to enforce a value that is strictly larger than System.currentTimeMillis() add an additional 1 to it. Set the range accordingly to prevent overflow (see assylias's comment).
Edited according to comments.
This is an approach if you want to be able to get numbers distributed across the entire range System.currentTimeMillis()..Long.MAX_VALUE:
long millis = System.currentTimeMillis();
long l = Math.min(Long.MAX_VALUE - millis, Math.abs(random.nextLong())) + millis;
Long.MAX_VALUE will be much more common than other results here though, in case that matters.
For a uniform distribution of times between currentTimeMillis and Long.MAX_VALUE, without overflow, you can use:
long time = System.currentTimeMillis();
long randomFutureTime = Math.abs(random.nextLong()) % (Long.MAX_VALUE - time) + time;
This may is useful to have real time of object creation, and two objects cannot have the same timestamp, so you can order them.
I use as UUID for my objects :
Const.DECAL_BIT = 20;
Const.DECAL_BIT_MASQUE = (Long.size() -1) - next 20;
private final Long timeCreate = (System.currentTimeMillis() << Const.DECAL_BIT)
+ (System.nanoTime() & Const.DECAL_BIT_MASQUE);
So you can have valid dates for 100 years : you multiply by 1M the internal datetime and had one second elapse time in nanosecond precision.
To read the date : Date d = Date((Long) timeCreate>> Const.DECAL_BIT);
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));
}
}