For a long time I measured passed time using
System.currentTimeMillis() and only recently figured out that I can also use
nanoTime(). However some results were not what I expected, as
nanoTime measures the time from an arbitrary point in time instead of
From the JavaDoc for
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. The value returned represents nanoseconds since some fixed but arbitrary time (perhaps in the future, so values may be negative). This method provides nanosecond precision, but not necessarily nanosecond accuracy. No guarantees are made about how frequently values change. Differences in successive calls that span greater than approximately 292 years (263 nanoseconds) will not accurately compute elapsed time due to numerical overflow.
For example, to measure how long some code takes to execute:long startTime = System.nanoTime(); // ... the code being measured ... long estimatedTime = System.nanoTime() - startTime;
I am confused by the arbitrary part. Measuring the passed time is only accurate if the reference timestamp is the same for both calls. However in the API documentation this is not guaranteed. I think that this was the cause for my mentioned issues. The time that is used is an implementation detail and therefore I cannot rely on it.
I am wondering about, when I can make good use of
nanoTime and in which cases it goes horribly wrong. The main use cases that come to mind are:
nanoTimetimestamps from different threads
nanoTimetimestamps from different instances of the same JVM (think, serialized timestamp from a previous application run, or passed as part of a message to a different JVM)
nanoTimetimestamps in different JVM implementations
There are some posts here on StackOverflow that address part of the issue, but largely leave the issue of the choosing of the time open:
Especially the link in the last one makes it clear that there are limitations when
nanoTime can be used, but without knowing these limitations exactly it seems inherently unsafe to use it at all as the functionality that is built upon it may fail.
The documentation should perhaps be explicit about this, but what they mean by “fixed but arbitrary” is that within the same JVM (i.e. within the same running JVM instance), the reference value is fixed.
So (1) is safe, but not beyond that.
Anything beyond that is depending on implementation quirks.