UPDATE: Instant has nothing to do with UTC in the timezone sense. It is related to UTC as a time standard only.
The major difference is the return type. They have different String representations because the types themselves have very different meanings.
Instant#now(Clock) returns Instant. An Instant is "[a]n instantaneous point on the time-line".
LocalDate#now(Clock) returns LocalDate. A LocalTime is "a description of the local time as seen on a wall clock".
As a result Instant#now(Clock) and LocalDate#now(Clock) mean very different things and naturally have different outcomes. The major thing they have in common is a name. Method names are dust. Refer to the types.
On a fixed Clock, both Instant.now(clock) and LocalDate.now(clock) will return constant values. The point of accepting Clock as a parameter is to be able to control things like the reference time or clock resolution.
Answer from Alain O'Dea on Stack OverflowNew java time api ? (Date vs Instant)
java - Which one is recommended: Instant.now().toEpochMilli() or System.currentTimeMillis() - Stack Overflow
Has the precision of Instant.now changed in Java 17?
Rely on Instant.now instead of System.currentTimeMillis() inside of Clock
Both are fine. And neither is recommended except for a minority of purposes.
What do you need milliseconds since the epoch for?
In Java, we can have many different ways to get the current timestamp,
For current timestamp just use Instant.now(). No need to convert to milliseconds.
Many methods from the first years of Java, also many in the standard library, took a long number of milliseconds since the epoch as argument. However, today I would consider that old-fashioned. See if you can find — or create — or more modern method that takes for instance an Instant as argument instead. Go object-oriented and don’t use a primitive long. It will make your code clearer and more self-explanatory.
As Eliott Frisch said in a comment, if this is for measuring elapsed time, you may prefer the higher resolution of System.nanoTime().
If you do need milliseconds since the epoch
Assuming that you have good reasons for wanting a count of milliseconds since the epoch, …
which one is recommended:
Instant.now().toEpochMilli()orSystem.currentTimeMillis()[?]
Opinions differ. Some will say that you should use java.time, the modern date and time API, for all of your date and time work. This would imply Instant here. Unsg java.time is generally a good habit since the date and time classes from Java 1.0 and 1.1 (Date, Calendar, TimeZone, DateFormat, SimpleDateFormat and others) are poorly designed and now long outdated, certainly not any that we should use anymore. On the other hand I am not aware of any design problem with System.curremtTimeMillis() in particular (except what I mentioned above about using a long count of milliseconds at all, which obviously is intrinsic to both Instant.now().toEpochMilli() and System.currentTimeMillis()).
If there is a slight performance difference between the two, I have a hard time imagining the situation where this will matter.
Take the option that you find more readable and less surprising in your context.
Similar questions
- JSR 310 :: System.currentTimeMillis() vs Instant.toEpochMilli() :: TimeZone
- Java current time different values in api
I want to add that System.nanoTime() is less about precision but more about accuracy.
System.currentTimeMillis() is based on the system clock, which is, most of the time, based on a quartz clock inside a computer. It is not accurate and it drifts. (VM is even worse since you don't have a physical clock and have to sync with the host) When your computer syncs this quartz clock with a global clock, you might even observe your clock jumps backward/forward because your local clock is too fast or slow.
On the other hand, System.nanoTime() is based on a monotonic clock. This clock has nothing to do with the actual time we humans speak. It only moves forward at a constant pace. It does not drift like the quartz clock and there is no sync required. This is why it is perfect for measuring elapses.
I'm just upgrading a project from Java 11 to Java 21 and found that Instant.now() has greater precision now since Java 17. Previously, it was microseconds and now it is nanoseconds.
This is reasonable as the Javadoc does say the precision is system dependent. Unfortunately, this makes the upgrade less trivial for us as this extra precision causes issues with some databases, and some clients of our API.
I can't find anything in the release notes and want to confirm that:
-
This is actually a change due to my upgrade and not some other factor I haven't realized
-
There isn't a flag that I can use to activate the previous behaviour
I'm a bit paranoid because I don't see why this wouldn't have occurred with Java 11 also but it seems to me that upgrading past Java 17 reliably reproduces the behaviour, on the same exact system.
Otherwise, I think I will need to wrap this method and truncate it in order to get back the previous behavior as I cannot update all of the clients in a backwards compatible way.