how to say 60 seconds with currentTimeMilis() - java

I'm trying to type out a code that outputs random words from a list, the user must type back as many words as possible before 60 seconds has elapsed I am using currentTimeMillis() to keep track of time so this is difficult for me to figure out I tried the code below and it said 6000000000000 is too large of a number but when I output the current/start time, it output 1512409897444 so this doesn't make sense to me.
long currentTime = System.currentTimeMillis();
long startTime = System.currentTimeMillis();
System.out.println(currentTime);
System.out.println(startTime);
while (startTime <= 6000000000000)
{
(etc. ect.)
}

What you want to do is compare the current time against the time you started and check if their difference is below 60 seconds, aka 60000 milli seconds:
long startTime = System.currentTimeMillis();
while ((System.currentTimeMillis() - startTime) <= 60000) {
// still under 60 seconds...
}

System.currentTimeMillis() returns a value that increases from an "epoch". You must subtract two time values to determine the amount of time that has elapsed.
long startTime = System.currentTimeMillis();
long elapsedTime = 0;
while (elapsedTime <= 60000) {
// etc, etc, etc
elapsedTime = System.currentTimeMillis() - startTime;
}

As others have already answered you have to subtract the starting time to the current time to determine if the difference is greather than 60 seconds (60,000 milliseconds). Also you can use TimeUnit to get a more readeable code:
long startTime = System.currentTimeMillis();
while (TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - startTime) <= 60) {
//do stuff
}
EDIT
If you are wondering why 6000000000000 gives you an error and the result of currentTimeMillis() (1512409897444) doesn't, is because they are different datatypes: int (32 bits) vs long (64 bits). The literal value 6000000000000 is interpreted as an int value which is greather than the max supported 32-bit signed int value (2,147,483,647) and the compiler doesn't allow that. It would work if you use a long literal instead 6000000000000L (note the L at the end). Signed long's max supported value is 9,223,372,036,854,775,807. The result of System.currentTimeMillis() is a long value hence 1512409897444 is valid. Read Primitive Data Types for further information.

Related

Is it possible to make this Java timer have better than ~15 ms resolution?

I've built a timing loop in Java. Simple. I'm avoiding Thread.sleep() because I thread scheduling overhead makes high-resolution delays impossible, so instead I used the following highly inefficient loop and got better results:
public static void timerBlockingDelayTest()
{
long DELAY_TARGET = 5;
long t0, t;
t0 = System.currentTimeMillis();
while (System.currentTimeMillis() < t0+DELAY_TARGET) {}
t = System.currentTimeMillis();
long offTargetAmt = Math.abs(t-t0-DELAY_TARGET);
System.out.format("Timer loop was off target by %d milliseconds\n",
offTargetAmt);
}
Things of which I am aware: operating system is not real-time, thread scheduling is at the whim of the OS, and GC can cause a delay.
What have I not considered?
On my machine (Windows 7 x64, i5, 2.4GHz) the best resolution I can get is about 15 ms. In fact, if I make DELAY_TARGET a multiple of 15, things work GREAT. However, if the target time is not near a multiple of 15, the offTargetAmt above will regularly be ~8 (ms).
I'm also aware of this post: high resolution timer in java
What the heck?! Is plus or minus ~8 ms seriously the best I can do??! I'm just looking for a "yes that's right" or "no you didn't consider ___" answer. Thanks
UPDATE:
Using System.nanoTime() seems to make a huge difference. I didn't believe it at first but here is my updated code that compares the two methods. See for yourself.
public static void timerBlockingDelayTest()
{
long DELAY_TARGET_MS = 5;
long NS_PER_MS = 1000000;
long DELAY_TARGET_NS = DELAY_TARGET_MS * NS_PER_MS;
long t0, t;
// Using System.currentTimeMillis()
t0 = System.currentTimeMillis();
while (System.currentTimeMillis() < t0+DELAY_TARGET_MS) {}
t = System.currentTimeMillis();
long msOffTarget = Math.abs(t-t0-DELAY_TARGET_MS);
// Using System.nanoTime()
t0 = System.nanoTime();
while (System.nanoTime() < t0+DELAY_TARGET_NS) {};
t = System.nanoTime();
long nsOffTarget = Math.abs(t-t0-DELAY_TARGET_NS);
// Compare the two methods
System.out.format("System.currentTimeMillis() method: ");
System.out.format(" - Off by %d ms (%d ns) \n",
msOffTarget, msOffTarget*NS_PER_MS);
System.out.format("System.nanoTime() method: ");
System.out.format(" - Off by %d ms (%d ns)\n",
nsOffTarget/NS_PER_MS, nsOffTarget);
}
Here is a sample output:
debug:
System.currentTimeMillis() method: - Off by 11 ms (11000000 ns)
System.nanoTime() method: - Off by 0 ms (109 ns)
BUILD SUCCESSFUL (total time: 0 seconds)
UPDATE 2 (hopefully the last):
Duh. Measuring the performance of a quantized or imperfect time function by itself is a little dumb. What I mean is that I was actually measuring the performance of currentTimeMillis() by itself, which isn't the most intelligent thing I've ever done. After realizing this, I PROFILED both of the above methods and found that indeed nanoTime() yields better resolution.
If you don't have a profiler, use nanoTime() to measure the duration of the currentTimeMillis() loop, like this:
public static void timerBlockingDelayTest()
{
long DELAY_TARGET_MS = 5;
long NS_PER_MS = 1000000;
long DELAY_TARGET_NS = DELAY_TARGET_MS * NS_PER_MS;
long t0ms, t0, t;
// Using System.currentTimeMillis()
t0 = System.nanoTime();
t0ms = System.currentTimeMillis();
while (System.currentTimeMillis() < t0ms+DELAY_TARGET_MS) {}
t = System.nanoTime();
long nsOffTarget1 = Math.abs(t-t0-DELAY_TARGET_NS);
// Using System.nanoTime()
t0 = System.nanoTime();
while (System.nanoTime() < t0+DELAY_TARGET_NS) {};
t = System.nanoTime();
long nsOffTarget2 = Math.abs(t-t0-DELAY_TARGET_NS);
// Compare the two methods
System.out.format("System.currentTimeMillis() method: ");
System.out.format(" - Off by %d ms (%d ns)\n",
nsOffTarget1/NS_PER_MS, nsOffTarget1);
System.out.format("System.nanoTime() method: ");
System.out.format(" - Off by %d ms (%d ns)\n",
nsOffTarget2/NS_PER_MS, nsOffTarget2);
}
At least that way I'm measured both delays by the same reference, which is only slightly more intelligent. The above gives an output like this:
debug:
System.currentTimeMillis() method: - Off by 4 ms (4040402 ns)
System.nanoTime() method: - Off by 0 ms (110 ns)
BUILD SUCCESSFUL (total time: 0 seconds)
Conclusion: use nanoTime(), and have a great day.
Use System.nanoTime instead. See this answer about the difference between nanoTime and currentTimeMillis.

Java How to get the difference between currentMillis and a timestamp in the past in seconds

Lets say i have long currentMillis and long oldMillis. The difference between the two timestamps is very tiny and always less than 1 second.
If i want to know the difference between the timestamps in milleseconds, i can do the following:
long difference = currentmillis-oldmillis;
And if i want to convert difference to seconds, i can just divide it by 1000. However if the difference in milliseconds is less than 1000 milliseconds(<1 second), dividing it by 1000 will result in 0.
How can i get the difference between the two timestamps if the difference is less than a second? For example, if the difference is 500 milliseconds, the desired output is 0.5 seconds.
Using float/double instead of long always returns 0.0 for some reason i don't understand.
My code:
private long oldmillis = 0, difference = 0;
private long calculateDifference()
{
long currentMillis = System.currentTimeMillis();
if (oldMillis == 0) oldMillis = currentMillis;
difference = currentMillis - oldMillis;
oldMillis = currentMillis;
return difference;
}
The method calculateDifference is called randomly with a small random time interval.
It sounds like you just need to convert the results into double before the division:
// This will work
double differenceMillis = currentMillis - oldMillis;
double differenceSeconds = differenceMillis / 1000;
// This will *not* work
double differenceSecondsBroken = (currentMillis - oldMillis) / 1000;
In the latter code, the division is performed using integer arithmetic, so you'll end up with a result of 0 that is then converted to a double.
An alternative which would work is to divide by 1000.0, which would force the arithmetic to be done using floating point:
double differenceSeconds = (currentMillis - oldMillis) / 1000.0;

Difference between two dates and percentage of current time java

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.

Java Long Returning Strange Value

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;
}

How to get a meaningful result from subtracting 2 nanoTime objects?

I created a filter that monitors the length of a request.
long start = System.nanoTime();
...
long end = System.nanoTime();
How can I get the number of milliseconds from this now?
(end - start) / 1000000
1 microsecond = 1000 nanoseconds
1 millisecond = 1000 microseconds
Note, that the result will be rounded down, but you usually don't get true nanosecond accuracy anyway (accuracy depends on the OS). From the Javadoc on nanoTime():
This method provides nanosecond precision, but not
necessarily nanosecond accuracy.
Also note that you can use the TimeUnit class to help with conversion. With older versions of Java, the following code might be an example to transform a processing time into some other time format:
long startTime = System.nanoTime();
//Processing in-between.
long endTime = System.nanoTime();
long duration = endTime - startTime;
duration = TimeUnit.SECONDS.convert(duration, TimeUnit.NANOSECONDS);
Note that newer versions of Java have shortcuts in the TimeUnit class.
The above sample will turn nanoseconds long into seconds. Also note that this truncates it so you do lose some precision. Therefore, if you switch to minutes then you will lose the precision of seconds. If you want to get a result of "12 minutes and 32 seconds" then you would have to do further processing with this solution.
TimeUnit#toMillis(long) (since Java 5)
TimeUnit.NANOSECONDS.toMillis(end - start);
OR
Duration#toMillis() (since Java 8)
Duration.ofNanos(end - start).toMillis()
OR
Duration#between(Temporal, Temporal) (since Java 8)
Instant start = Instant.now();
...
Instant end = Instant.now();
Duration.between(start, end).toMillis()
OR
ChronoUnit.html#between(Temporal, Temporal) (since Java 8)
Instant start = Instant.now();
...
Instant end = Instant.now();
ChronoUnit.MILLIS.between(start, end)
Just subtract them and divide result by 10^6.
1 nanosecond is 10^-9 seconds and, correspondingly, 10^-6 milliseconds.
http://en.wikipedia.org/wiki/Nano-
You could just use System.currentTimeMillis().
Caveat:
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.
To get a meaningful result:
void procedure ( ... )
{
...
}
double measureProcedure ( double epsilon , ... )
{
double mean ;
double stderr = 2 * epsilon ;
while ( stderr > epsilon )
{
long start = System.nanoTime();
procedure ( ... ) ;
long end = System.nanoTime();
// recalculate mean , stderr
}
return ( mean / 1000000 ) ;
}

Categories

Resources