Will System.currentTimeMillis always return a value >= previous calls?

JavaLinux

Java Problem Overview


<https://docs.oracle.com/javase/6/docs/api/java/lang/System.html#currentTimeMillis()> says:

> 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.

It is not clear to me if I am guaranteed that this code will always print ever increasing (or the same) numbers.

while (1) { 
    System.out.println(System.currentTimeMillis() );
}

Java Solutions


Solution 1 - Java

The short answer is no, System.currentTimeMillis() is not monotonic. It is based on system time, and hence can be subject to variation either way (forward or backward) in the case of clock adjustments (e.g. via NTP).

System.nanoTime() is monotonic, if and only if the underlying platform supports CLOCK_MONOTONIC -- see the comments on Java bug report 6458294 for a good writeup on some circumstances where this is/isn't true.

(And, as an additional anecdote, I have personally observed (several times) System.currentTimeMillis() run 'backwards', in the absence of clock adjustments, across threads -- that is, a call to that method in one thread returned a lower value than a call in another thread, even though it occurred chronologically after it in 'real-time')

If you need a monotonic source, System.nanoTime() on a platform supporting monotonicity is your best option.

Solution 2 - Java

No, it will not always be >= all previous calls.

  • It might not increase every time if you call it several times in quick succession from the same thread (I know this is the = part of >=, but the behavior often surprises people).

  • If you call it several times in quick succession from multiple threads, it might do any number of things -- it could go slightly back in time across threads by a very small amount, depending on implementation and random chance.

  • Most seriously, the value might go back in time by a large amount if the user (rare) or an NTP sync (potentially common) adjusts the system clock.

Solution 3 - Java

It couldn't possibly be guaranteed to be increasing, based on the fact that the user could potentially change the system time between calls.

Besides that, it should stay increasing since it represents milliseconds since the epoch. If it were a normal "wall time", you would have to worry about time changes on leap day or on daylight savings changeover.

Solution 4 - Java

If you want a value which is monotonicly increasing you can do something like.

public enum Time {
    ;
    private static long lastTime;
    public synchronized static long increasingTimeMillis() {
        long now = System.currentTimeMillis();
        if (now > lastTime)
            return lastTime = now;
        return ++lastTime;
    }
}

As long as you call this less than a thousand times per second, your increasing time won't drift too far from the real time but will be unique. (This can work, even if you restart your application)

Solution 5 - Java

@Mark Rushakoff is right; nanoTime() might be slightly more reliable.

Addendum: note these caveats, cited by @Steven Schlansker.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Question1984isnotamanualView Question on Stackoverflow
Solution 1 - JavaCowanView Answer on Stackoverflow
Solution 2 - JavaSean ReillyView Answer on Stackoverflow
Solution 3 - JavaMark RushakoffView Answer on Stackoverflow
Solution 4 - JavaPeter LawreyView Answer on Stackoverflow
Solution 5 - JavatrashgodView Answer on Stackoverflow