1

I was about to use System.currentTimeMillis() in Eclipse when I noticed the following paragraph appear in its Javadoc:

Returns the current system time in milliseconds since January 1, 1970
00:00:00 UTC. This method shouldn't be used for measuring timeouts or
other elapsed time measurements, as changing the system time can affect
the results.

So that means I can't rely on System.currentTimeMillis() if I wanted to specifically maintain a reference to this current point in time. What is the most accurate way to do it, then? Do the three methods mark the current time differently from each other?

UPDATE: What I'm trying to do is measure the difference between two points in time in two separate program runs. My fear is that if I use System.currentTimeMillis() and the user plays with the system time after the first run, I might get a bizarre unexpected value during the second.


  • I guess you can use it... as long as you don't change the system time. :) Anyway, on Windows it won't be very accurate. - Tudor
  • Related: stackoverflow.com/questions/11591000/… If you need to make sure time changes don't affect your measurement: System.nanotime(). - assylias
  • Do you just want to measure time differences? Or do you really want a reference to the current time? - João Silva
  • I'm going to measure time differences for over long periods within a day. Is that any different from the need to reference the current time though? - Matt Quiros

4 답변


4

If you want to refer to a specific point in time, you can definitely rely on System.currentTimeInMillis(). The three methods you describe will mark the time the same way, the difference is just what kind of object it is wrapped in. Use the variant that you need in your program.

If you want to measure the difference between two points in time during a program run, use System.nanoTime() instead.

To get the time difference between two points in time in two separate program runs you will have to rely on external time sources if you are afraid that the user might play around with the system clock. For example, you can take a look at Java SNTP Client.


  • What if I want to measure the difference between two points in time in two separate program runs? From my understanding, if I use System.currentTimeInMillis(), my user can somehow play around with the system time and I might get an unexpected value in the second run. - Matt Quiros
  • @mattquiros: See edit. - Keppil

6

You should use System.nanoTime(), from the API docs:

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.


  • I've edited to superscript the power, otherwise you get 263 nanoseconds, which is a fair bit shorter than 292 years... - Rich
  • But isn't this simply the same as currentTimeInMillis(), only precise down to the nanosecond level, but can still be made to misbehave if the system time on the device or computer was changed? - Matt Quiros
  • @mattquiros no, "...not related to any other notion of system or wall-clock time." - dacwe
  • @mattquiros Note also that it is not "precise down to the nanosecond level" even if the name suggests it. As pointed out in the answer: "This method provides nanosecond precision, but not necessarily nanosecond accuracy. No guarantees are made about how frequently values change." - assylias
  • Oh okay. I was thinking twice because of the "current value of the most precise available system timer" part (first sentence). - Matt Quiros

0

use System.nanoTime() than System.currentTimeInMillis()


0

A feature of System.currentTimeMillis() is that it is corrected periodically to make it more accurate in the long run. This can mean time goes backwards or jumps forwards when corrected.

A feature of System.nanoTime() is that it is monotonically increasing. Its isn't guaranteed to be related between JVMs but on many systems it happens to be approximately the time since the last processor reset. i.e. it will be reset on a reboot.

Linked


Related

Latest