I'm a novice in Java programming and I wanted to implement the timer class in my program.
I'm making a mini time-based testing system which outputs a question then time remaining and then the answer choices
Example:
Which operator returns the remainder of integer division? (4 minutes left...)
A. %
B./
C. *
D. None of the above
The escape sequence that represents the new line character is: (1 minutes left...)
A. \r
B. \t
C. \n
D. \
I don't know how to get that time remaining part. It's supposed to run in background and change right when the next question comes up
You can accomplish what you're trying to do without using timer, which will probably be easier, as you're new.
There's a function called System.currentTimeMillis() that returns the current system time in milliseconds. From that, you can:
Store the time when you start
Do some other stuff
Check the time when you stop, and calculate the time remaining
As such:
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
// Do other stuff...
long stopTime = System.currentTimeMillis();
int elapsedSeconds = (int)((stopTime - startTime) / 1000);
System.out.println(elapsedSeconds + " seconds elapsed");
}
Related
I'm doing a homework assignment where we're testing the runtime of a couple algorithms (greatest common divisor, or GCD) using 10-digit prime numbers.
We are to capture the runtime as milliseconds, which I capture using System.currentTimeMillis().
The way I do it is to have a start time variable and a stop time variable, then find the difference between those two in another variable.
So far, it works perfectly for one method, but returns 0 or 1 for the other method.
I went through the debugger, and it seemed to work correctly, but when I run it, it returns 0 or 1.
Here are the variables I'm using and the main method. The commented-out line works as intended, but the fastgcd method is the one that returns 0 or 1.
public class GCD {
public static long startTime;
public static long stopTime;
public static long elapsedTime;
public GCD(){
}
public static void main(String[] args){
startTime = System.currentTimeMillis();
//System.out.println(gcd(3267000013L, 1500450271L));
System.out.println(fastgcd(3267000013L, 1500450271L));
stopTime = System.currentTimeMillis();
elapsedTime = stopTime - startTime;
System.out.println(Long.toString(elapsedTime));
}
Here's the method that works:
public static String gcd(long a, long b) {
long n = Long.min(a, b);
for (long i = n; i >= 1; i--) {
if (a % i == 0 && b % i == 0) {
return "Done";
}
}
// If error
return null;
}
And here's the method that doesn't work:
public static String fastgcd(long a, long b){
if(b == 0){
return "Done";
}
else{
return fastgcd(b, a%b);
}
}
So for the method that works, I will get somewhere between 12000 - 12500 milliseconds for a 10-digit number.
The fastgcd method returns 0 or 1 milliseconds, which isn't right, especially a 10-digit prime number.
No idea where it's going wrong...
Your code is fine (in terms of getting time), and the values that you're getting are "correct". What you're measuring is wall-clock time (see here), which is inherently slightly inaccurate, and also not granular enough to measure code that is running as quickly as your fastgcd method.
For measuring elapsed time with a high degree of precision, use System.nanoTime() instead of System.currentTimeMillis().
If you run your method and check the recursion count, it will be called recursively only 19 times. And for these modern days compiler and machines, it is not huge operation. So completing it in 1 millisecond is totally justified. If you check it in nanoseconds using System.nanoTime(), fastgcd is taking around 280675 nanoseconds on my Windows machine Java 8, 32 GB RAM and 8th Gen Core I7. So nothing going wrong here.
I'm trying to make a timing mechanism using threads, and I'm having a problem in getting the time difference between two Dates, and using that difference to get a current percentage of the time left. Here is the concept I'm trying to prototype:
And here is my implementation:
long startMilisecs = System.currentTimeMillis();
long currentMilisecs;
long endDateMilisecs = getEndDate().getTime();
int diffMillisecs = ((int)(endDateMilisecs - startMilisecs) / 1000) / 60;
int currPerc;
while (startMilisecs <= endDateMilisecs)
{
currentMilisecs = (int) System.currentTimeMillis();
currPerc = ((int)currentMilisecs * 100) / diffMillisecs;
System.out.println(" Current Percentage: " + currPerc);
}
The problem with this code is that the percentage is not starting from 0 but rather in the 20's to 40 percent.
Can you tell me what is wrong with this? and for this problem I have been restricted to using only threads.
check below:
public static int getPercentageLeft(Date start, Date end) {
long now = System.currentTimeMillis();
long s = start.getTime();
long e = end.getTime();
if (s >= e || now >= e) {
return 0;
}
if (now <= s) {
return 100;
}
return (int) ((e - now) * 100 / (e - s));
}
You need to subtract the starting time like this
currPerc = ((currentMilisecs - startMilisecs) * 100) / diffMillisecs;
to get the correct percentage.
The problem is with the System.currentTimeMillis();. Taken from the javadoc:
public static long currentTimeMillis()
Returns the current time in milliseconds. Note that while the unit of
time of the return value is a millisecond, the granularity of the
value depends on the underlying operating system and may be larger.
For example, many operating systems measure time in units of tens of
milliseconds.
See the description of the class Date for a discussion of slight
discrepancies that may arise between "computer time" and coordinated
universal time (UTC).
Returns:
the difference, measured in milliseconds, between the current time and midnight, January 1, 1970 UTC.
So your current time in milliseconds is based on January 1, 1970 UTC, not on your start date.
You need to calculate current time by subtracting start time from the value that is given by System.currentTimeMillis();.
I am basically formulating your linked image here. Other alternative calculations can also be carried out.
I have just started to learn Java, and I want to make random array and to measure time. I used System.currentTimeMillis(); at the beginning of filling my array, and the same at then and. Then I wanted to convert milliseconds to nanoseconds and used long total=TimeUnit.MILLISECONDS.toNanos(time1); but trouble occurred:
import java.util.*;
import java.util.concurrent.TimeUnit;
public class main {
public static void main(String[] args) {
long time1,time2,time3;
int [] array = new int[10];
Random rand =new Random(100);
time1=System.currentTimeMillis();
for(int i=0;i<array.length;i++){
array[i]=rand.nextInt(100);
}
time2=System.currentTimeMillis()-time1;
long total=TimeUnit.MILLISECONDS.toNanos(time1);
System.out.println("Time is:"+time1
);
}
}
In the end I got 'Time is:1361703051169;' I think that something's wrong with this.
Well, instead of using
System.currentTimeMillis()
you can use
System.nanoTime()
That provides the time in nanoseconds, without having to do any conversion
Also i think this maybe wrong:
long total=TimeUnit.MILLISECONDS.toNanos(time1);
System.out.println("Time is:"+time1);
Maybe you wanted to print total instead of time1?
EDIT
Please note that, as Mark Rotteveel said, in the System.nanoTime and System.currentTimeMillis() are different.
From Javadocs:
System.currentTimeMillis()
Returns the current time in milliseconds.
Note that while the unit of time of the return value is a millisecond, the granularity of the value depends on the underlying operating system and may be larger.
For example, many operating systems measure time in units of tens of milliseconds.
and
System.nanoTime()
Returns the current value of the most precise available system timer, in nanoseconds.
This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time.
You may want to rewrite your code like this:
public static void main(String[] args) {
long start, end, difference;
start = System.nanoTime();
//code to meassure here
end = System.nanoTime();
difference = end - start;
System.out.println("Time taken:" + difference);
}
You can do a simple conversion with java.time.Duration like so: Duration.ofMillis(numberOfMilliseconds).toNanos()
In my android program I am using two Calendar instances to get the elapsed time in my program, first I set a level starting time as follows:
level_Start_TimeCal = Calendar.getInstance();
and in my thread I am calculating elapsed time as follows:
level_current_TimeCal = Calendar.getInstance();
gameTime = level_current_TimeCal.getTimeInMillis()- level_Start_TimeCal.getTimeInMillis();
dsecs = (gameTime / 1000)%60;
dminutes = (gameTime / (60 * 1000))%60;
dhours = (gameTime / (60 * 60 * 1000))%60;
Recently I came to read the following:
Calendar's getInstance method returns a Calendar object whose calendar
fields have been initialized with the current date and time
I want to know if I am in right path?
Am I creating an object each time the thread running?
If yes is there any alternative to avoid creating unwanted objects and calculating elapsed time?
Final question: at some point I want to reset the time in my restart method I reset it by just calling getInstance in my reset method as follows:
public void restart() {
level_Start_TimeCal = Calendar.getInstance();
}
Is this the correct way to reset the Calendar?
The best way to calculate elapsed time is to use System.nanotime().
long start = System.nanoTime();
//do something
long end = System.nanoTime();
//to get the elapsed time, you can use the TimeUnit utility methods:
long elapsedInNanos = end - start;
long elapsedInSeconds = TimeUnit.SECONDS.convert(elapsedInNanos, TimeUnit.NANOSECONDS);
Note that it is not a useful method to access absolute time.
Regarding the following method:
private long getCountdownLeft(Integer seconds) {
long now = System.currentTimeMillis();
long elapsedMillis = now - seconds;
long millisLeft = seconds * 1000 - elapsedMillis;
return millisLeft/1000;
}
public static void Main(String[] args) {
getApi().getLogger.debug("TimeLeft " + getCountDownLeft(3600)); //base time
}
It is returning a value of something like: -12039495960, why is that?
If 3600 is the value you are passing in, you're obviously going to get a negative value.
Print out System.currentTimeMillis(), youll see that it is quite a large value.
currentTimeMillis() is defined as:
the difference, measured in milliseconds, between the current time and midnight, January 1, 1970 UTC.
It's extremely hard to tell based on the information given, but for this method to work, seconds must be initialized with System.currentTimeMillis() / 1000.
Boiled down into one statement, you have
return (seconds * 999 - System.currentTimeMillis())/1000;
If System.currentTimeMillis() is unix time (1343874904292 right now), then OF COURSE this will be negative. I'm not sure what you meant to write, but this obviously not it...
Your problem is you are subtracting seconds from milliseconds.
Try this:
long elapsedMillis = now - (seconds * 1000); // convert seconds to millseconds
It seems you are really just trying to do this:
private long getCountdownLeft(Integer seconds) {
return seconds * 1000;
}