I already read an answer about if it's possible in Java 8 to get the current microseconds and the answer was no, but is it possible now in Java11?
The solution by using System.nanoTime() * 1000 is too inefficient. Note: The Goal is NOT to get the exact time in nanoseconds, obviously that's not working like this.
I would appreciate any help :)
CodePudding user response:
As before, Instant.now()
uses the most accurate time source available to the system. Depending on the system, there may not be anything finer-grained than System.currentTimeMillis
.
As mentioned in the comments, System.nanoTime() / 1000
can be used for measuring the time between values, but doesn't give you anything like "the current time" -- you can't tell from it, for example, whether or not it's 3:00 PM.
If you need to measure or calculate e.g. the time between events in your program, there is nothing that will do better for you than System.nanoTime
.
CodePudding user response:
The Answer by Wasserman is correct. Here are more thoughts.
Not real-time
You commented:
When you try to do a very exact scheduler
Conventional implementations of Java, and conventional computer hardware, are not “very exact” along the scale of nanosecond and microsecond that you seemed to be targeting.
For “very exact” scheduling, you would have to use special hardware with special software. Look for the buzzword real-time, such as real-time Java.
System.nanoTime()
You said:
The solution by using System.nanoTime() * 1000 is too inefficient. Note: The Goal is NOT to get the exact time in nanoseconds
Be aware that System.nanoTime()
does not tell you the current time.
System.nanoTime()
tells you the approximate amount of nanoseconds that have elapsed since some arbitrarily chosen moment. In some implementations of Java, that moment may have been when the JVM was launched, or when the computer was booted, or something else. But you cannot count on that origin, nor should you care about the origin.
Represent elapsed time using Duration
class.
To capture elapsed time in Java for micro-benchmarking:
long start = System.nanoTime() ;
…
Duration elapsed = Duration.between( start , System.nanoTime() ) ;
You can interrogate the Duration
for its parts such as nanoseconds, whole seconds, minutes, and hours.
You said:
System.nanoTime() * 1000 is too inefficient
You must have meant:
( start - System.nanoTime() ) / 1_000
… to get a count of elapsed microseconds.
And, no, dividing or multiplying integers is not “inefficient“. If you care about optimizing for integer division operations, you should not be using conventional Java on conventional hardware, as discussed in section above.
Instant.now()
If you want to capture elapsed time as seen by human clocks:
Instant start = Instant.now() ; // May be precise to milliseconds, microseconds, or such depending on your implementation of Java and your host computer hardware clock.
…
Instant end = Instant.now() ;
To represent that elapsed time unattached to the timeline, use Duration
.
Duration elapsed = Duration.between( start , end ) ;
To represent that elapsed time attached to the timeline, write a class storing a pair of Instant
objects.
record SpanOfTime ( Instant start , Instant end ) {}
Or better yet, add the ThreeTen-Extra library to your project. This library brings classes that add functionality to the built-in java.time classes. One of these is Interval
, with handy comparison methods such as abuts
, contains
, encloses
, overlaps
, etc.