The difference between JAVA System.nanoTime() and GO time.Now().UnixNano()

JAVA System.nanoTime()

    public static void main(String[] args) {
        long nano = System.nanoTime();
        System.out.println(nano);
    }

Output: 701863191254000, this value is a bit strange, System.currentTimeMillis() is not 1000000 times that of System.nanoTime().

What is this value? First look at the source code comments:

Returns the current value of the running Java Virtual Machine's high-resolution time source, in nanoseconds.
返回正在运行的Java虚拟机的高分辨率时间源的当前值,单位为纳秒。
(我理解就是指,这个纳秒值就是Java虚拟机能获取的最高精度的时间值了。)


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.
这种方法只能用于测量经过的时间,与系统或挂钟时间的任何其他概念无关。返回的值表示自某个固定但任意的起始时间以来的纳秒(可能在将来,因此值可能为负值)。在Java虚拟机的实例中,此方法的所有调用都使用相同的原点;其他虚拟机实例可能使用不同的来源。
(1、这个纳秒时间跟标准时间无关,要用也只能用来比如计算方法执行时间等。2、这个值的起始时间不是笃定的。3、不同虚拟机下边获取这个时间可能还不同。)

This method provides nanosecond precision, but not necessarily nanosecond resolution (that is, how frequently the value changes) - no guarantees are made except that the resolution is at least as good as that of currentTimeMillis().
此方法提供纳秒精度,但不一定是纳秒分辨率(即值更改的频率)-除了分辨率至少与currentTimeMillis()一样好之外,没有任何保证。


Differences in successive calls that span greater than approximately 292 years (263 nanoseconds) will not correctly compute elapsed time due to numerical overflow.
由于数值溢出,跨度超过约292年(263纳秒)的连续调用之间的差异将无法正确计算所用时间。


The values returned by this method become meaningful only when the difference between two such values, obtained within the same instance of a Java virtual machine, is computed.
只有当计算在Java虚拟机的同一实例中获得的两个这样的值之间的差时,此方法返回的值才有意义。

How to calculate it, look at the analysis of people who understand C: Detailed explanation of System.currentTimeMillis and nanoTime principles of JVM source code analysis

There is a key point in it:

The parameter CLOCK_MONOTONIC is passed in when taking nanoseconds in our JVM, so the following method will be called

The tv_sec and tv_nsec of wall_to_monotonic above are both negative numbers, which are set when the system starts and initializes, and the startup time is recorded. Therefore, nanoTime actually calculates a relative time, relative to the time when the system starts. 

And System.currentTimeMillis() returns the number of milliseconds from 1970/01/01 08:00:00 to the current time.

GO time.Now().UnixNano()

time.Now().UnixNano()

Execution result: 1681209667509687900, the result is too different from the nanosecond time obtained by JAVA. Look at the source code comments of GO:

// UnixNano returns t as a Unix time, the number of nanoseconds elapsed
// since January 1, 1970 UTC. The result is undefined if the Unix time
// in nanoseconds cannot be represented by an int64 (a date before the year
// 1678 or after 2262). Note that this means the result of calling UnixNano
// on the zero Time is undefined. The result does not depend on the
// location associated with t.
func (t Time) UnixNano() int64 {
	return (t.unixSec())*1e9 + int64(t.nsec())
}

The point is this sentence: UnixNano returns t as the Unix time, the number of nanoseconds elapsed since January 1, 1970 UTC.

This is the reason why GO and JAVA ( nanoTime actually calculates a relative time, relative to the time when the system starts.  ) are so different.

How to use JAVA to calculate the same nanosecond as GO? You can leave a message to discuss. . .

Guess you like

Origin blog.csdn.net/h363659487/article/details/130090750