My program reads in data from various different sources and needs to match it up using timestamps. Some of the timestamps were provided by a call to System.currentTimeMillis() in the application which created the files, and I need to know how accurate this is, so that I can account for any rounding errors which might have occurred. This isn't actually as obvious as it sounds, as I know that this depends on the accuracy of time measurement by the hardware, OS, and I think the JVM even has its own notion of time which is only required to be consistent with UTC every noon, but I believe that a call to currentTimeMillis() bypasses this and retrieves the time directly from the OS (is this correct?).
In principle, my question is: does System.currentTimeMillis() actually give the time accurate to the nearest millisecond on Linux, Mac OS and Windows (and since which versions - I know, for example, that Windows only used to be accurate to the nearest 15/16 milliseconds).
Answer: don't know, and it probably varies from machine to machine. Maybe somebody else will know more.
The documentation is not at all sanguine about its precision, and scrolling down to the nanoTime method doesn't inspire me with confidence either. I have tried nanoTime on a Linux box before and it seems to count time elapsed since I booted the machine. That may be different on Windows®; I have never tried.
I tried this on Fedora25 using an Intel® Celeron(R) CPU 1037U @ 1.80GHz × 2 with 4GB of ram:-...and repeatedly got 5 or 6. Two consecutive millisecond calls without the intervening loop returned a difference of 0. So I can't find any evidence of precision to the nearest millisecond.
I did take some delight in writing that semicolon instead of the loop however
Campbell Ritchie wrote:The documentation is not at all sanguine about its precision
It's explicitly vague:
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.
I've seen increments of up to 10ms, so never use it for real precision counters, only as an indication.
Campbell Ritchie wrote:and scrolling down to the nanoTime method doesn't inspire me with confidence either. I have tried nanoTime on a Linux box before and it seems to count time elapsed since I booted the machine. That may be different on Windows®; I have never tried.
It doesn't really matter, as long as you remember what the documentation does say:
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 origin time (perhaps in the future, so values may be negative). The same origin is used by all invocations of this method in an instance of a Java virtual machine; other virtual machine instances are likely to use a different origin.
So don't assume it's System.currentTimeMillis() * 1000 or anything, and don't migrate its values to different machines or even persist it and reuse when restarting the application on the same machine.