System.nanoTime and System.currentTimeMillis() - java

I am using JDK8 on Windows and JDK8 on Linux
When I run System.nanoTime()/System.currentTimeMillis() on windows, the result is 49,
System.nanoTime(): 74786833960332
System.currentTimeMillis():1507786236263
When run it on Linux, the result is 26236
System.nanoTime(): 39560110918205325
System.currentTimeMillis():1507786262105
I am confused with the result, that the two values are different so much.
Also, I thought that nanoTime is 1,000,000 times milliseconds, so that the two values above both look wrong to me(that is, both of them should be approximately 1000000)

Apples and Oranges
System.nanotime has nothing to do with current date and time-of-day. Its purpose is for calculating elapsed time.
Your math and your comparison to System.currentTimeMillis() makes no sense at all. The two functions are incomparable.
Read the documentation before posting to Stack Overflow.
For date-time handling you should not be using the System class at all. Instead use the industry-leading java.time classes built into Java 8 and later.
If you want current moment in UTC, call Instant.now().
If you want current moment in a time zone, call ZonedDateTime.now.
In Java 9 and later, both classes use a new implementation of Clock to capture the current moment in a resolution up to nanoseconds. But keep in mind that mainstream computers lack a hardware clock with such fine sensitivity. Microseconds is likely the finest resolution you'll see in the real world as of 2017.

According to System.nanotime() docs it is not system time in nanoseconds and it is not related to System.currenTimeMillis. It is platform dependent (this is why the difference) nanoseconds generator and it is used for measuring time elapsed between two invocations.

From the Java System documentation:
[System.nanoTime] Returns the current value of the running Java Virtual Machine's high-resolution time source, in nanoseconds.
This means System.nanoTime() returns the elapsed running time of the JVM in nanos, whereas System.currentTimeMillis() returns the time in milliseconds since midnight, January 1, 1970 UTC.
This results in a non-consistent nanoTime over each run.

Related

Java 11 get current Microseconds?

I already read an answer about if it's possible in Java 8 to get the current microseconds and the answer was no, but is it possible now in Java11?
The solution by using System.nanoTime() * 1000 is too inefficient.
Note: The Goal is NOT to get the exact current time in nanoseconds (for example 12:00 PM), obviously that's not working like this.
I would appreciate any help :)
As before, Instant.now() uses the most accurate time source available to the system. Depending on the system, there may not be anything finer-grained than System.currentTimeMillis.
As mentioned in the comments, System.nanoTime() / 1000 can be used for measuring the time between values, but doesn't give you anything like "the current time" -- you can't tell from it, for example, whether or not it's 3:00 PM.
If you need to measure or calculate e.g. the time between events in your program, there is nothing that will do better for you than System.nanoTime.
The Answer by Wasserman is correct. Here are more thoughts.
Not real-time
You commented:
When you try to do a very exact scheduler
Conventional implementations of Java, and conventional computer hardware, are not “very exact” along the scale of nanosecond and microsecond that you seemed to be targeting.
For “very exact” scheduling, you would have to use special hardware with special software. Look for the buzzword real-time, such as real-time Java.
System.nanoTime()
You said:
The solution by using System.nanoTime() * 1000 is too inefficient. Note: The Goal is NOT to get the exact time in nanoseconds
Be aware that System.nanoTime() does not tell you the current time.
System.nanoTime() tells you the approximate amount of nanoseconds that have elapsed since some arbitrarily chosen moment. In some implementations of Java, that moment may have been when the JVM was launched, or when the computer was booted, or something else. But you cannot count on that origin, nor should you care about the origin.
Represent elapsed time using Duration class.
To capture elapsed time in Java for micro-benchmarking:
long start = System.nanoTime() ;
…
Duration elapsed = Duration.between( start , System.nanoTime() ) ;
You can interrogate the Duration for its parts such as nanoseconds, whole seconds, minutes, and hours.
You said:
System.nanoTime() * 1000 is too inefficient
You must have meant:
( start - System.nanoTime() ) / 1_000
… to get a count of elapsed microseconds.
And, no, dividing or multiplying integers is not “inefficient“. If you care about optimizing for integer division operations, you should not be using conventional Java on conventional hardware, as discussed in section above.
Instant.now()
If you want to capture elapsed time as seen by human clocks:
Instant start = Instant.now() ; // May be precise to milliseconds, microseconds, or such depending on your implementation of Java and your host computer hardware clock.
…
Instant end = Instant.now() ;
To represent that elapsed time unattached to the timeline, use Duration.
Duration elapsed = Duration.between( start , end ) ;
To represent that elapsed time attached to the timeline, write a class storing a pair of Instant objects.
record SpanOfTime ( Instant start , Instant end ) {}
Or better yet, add the ThreeTen-Extra library to your project. This library brings classes that add functionality to the built-in java.time classes. One of these is Interval, with handy comparison methods such as abuts, contains, encloses, overlaps, etc.

Difference B/W Clock.systemUTC() And System.currentTimeMillis()

Clock.systemUTC() docs say that this method may use System.currentTimeMillis() or a higher resolution clock if available. What clock does System.currentTimeMillis() use then? Can there be a difference in the granularity of these two values?
Can there be a difference in the granularity of these two values?
The Clock class has 2 methods for retrieving the current time:
millis()
instant()
Since instant() returns an Instant, which can represent time with a precision of nano-seconds, the answer is obvious.
Answer: Yes.
What clock does System.currentTimeMillis() use then?
If you look at the source code of Clock.systemUTC(), you will find that it uses an internal SystemClock class. In a comment in the millis() method, it says (quoting Java 15):
System.currentTimeMillis() and VM.getNanoTimeAdjustment(offset)
use the same time source - System.currentTimeMillis() simply
limits the resolution to milliseconds.
So we take the faster path and call System.currentTimeMillis()
directly - in order to avoid the performance penalty of
VM.getNanoTimeAdjustment(offset) which is less efficient.
Answer: System.currentTimeMillis() and Clock.instant() use the same time source.

How to convert System.currentMillisSeconds to a TemporalAccessor

I need to convert a standard long System.currentmillis to a temporal accessor and have no clue how to even begin.
Instant is a TemporalAccessor, so you can create an Instant from a number of milliseconds since the epoch:
TemporalAccessor ta = Instant.ofEpochMilli(System.currentTimeMillis());
Note that the docs for System.currentTimeMillis says that the granularity of the value depends on the OS, so it might not be the exact time in milliseconds.
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.

Java api to access Linux nanos since epoch

Linux time man page specifies that the clock time structure contains nanoseconds since epoch. Is this exposed in Java in any api ? In other words , why is there no JDK api like System.currentNanos() that returns nanos since Epoch ?
Note : I know System.nanoTime() returns nanos , but its NOT with reference to Epoch time , and cannot be used across VMs for time comparison.
Edit : I am not asking how to format a date value - I am asking how to query the system for nanotime SINCE epoch ?
Because Java is intended to work across a whole variety of devices, it is not so closely tied to any one such platform.

Why does the new Java 8 Date Time API not have nanosecond precision? [duplicate]

This question already has answers here:
Java 8 Instant.now() with nanosecond resolution?
(5 answers)
Closed 6 years ago.
One of the features of the new Date Time API in Java 8 is supposed to be nanosecond precision. However when I print the current Date Time to the console like so
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("yyyy-MM-dd'T'HH:mm:ss,nnnnnnnnnZ");
System.out.println(OffsetDateTime.now().format(formatter));
I only see millisecond precision: 2015-11-02T12:33:26,746000000+0100
The operating system does seem to support nanosecond precision. When I print the current date time via the Terminal
date -Ins
I see 2015-11-02T12:33:26,746134417+0100
How do I get nanosecond precision in Java? I'm running Oracle Java 1.8.0_66 on Ubuntu 14.04 64-bit
The java.time API in general does have nanosecond precision. For example:
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("yyyy-MM-dd'T'HH:mm:ss,nnnnnnnnnZ");
OffsetDateTime odt = OffsetDateTime.of(2015, 11, 2, 12, 38, 0, 123456789, ZoneOffset.UTC);
System.out.println(odt.format(formatter));
Output:
2015-11-02T12:38:00,123456789+0000
However, it's the clock value returned by OffsetDateTime.now() which is returning a value which only has milliseconds.
From Clock implementation in Java 8:
The clock implementation provided here is based on System.currentTimeMillis(). That method provides little to no guarantee about the accuracy of the clock. Applications requiring a more accurate clock must implement this abstract class themselves using a different external clock, such as an NTP server.
So there's nothing inherently imprecise here - just the default implementation of Clock using System.currentTimeMillis(). You could potentially create your own more precise subclass. However, you should note that adding more precision without adding more accuracy probably isn't terribly useful. (There are times when it might be, admittedly...)
To make an important addition to the answer of Jon Skeet, Java 9 is supposed to deliver a clock in improved precision - see the bug log. Background: On many operating systems (especially Linux), there are better clocks available.
The Java SE 8 specification for java.time.Clock states that "The
system factory methods provide clocks based on the best available
system clock. This may use System.currentTimeMillis(), or a higher
resolution clock if one is available.". In JDK 8 the implementation
of the clock returned was based on System.currentTimeMillis(), and
thus has only a millisecond resolution. In JDK 9, the implementation
is based on the underlying native clock that
System.currentTimeMillis() is using, providing the maximum resolution
available from that clock. On most systems this can be microseconds,
or sometimes even tenth of microseconds.
An application making the assumption that the clock returned by these
system factory methods will always have milliseconds precision and
actively depends on it, may therefore need to be updated in order to
take into account the possibility of a greater resolution, as was
stated in the API documentation.
It should also be noted the (exotic) fact that second precision will not exist near leap seconds - not even in Java 9.

Categories

Resources