JDK-6709908 : System.currentTimeNanos() to support nanosecond precision
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 7
  • Priority: P5
  • Status: Closed
  • Resolution: Not an Issue
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2008-06-03
  • Updated: 2020-04-10
  • Resolved: 2017-07-20
Related Reports
Relates :  
Relates :  
Description
A DESCRIPTION OF THE REQUEST :
JSR 310 (Public Project for the Date and Time API) will introduce a javax.time.Clock.system() call that can support nanosecond precision.

Introducing java.lang.System.currentTimeNanos() that returns a two-element long array containing {seconds, nanos} since epoch would go together well with JSR-310.


JUSTIFICATION :
Solaris and Linux already support nanosecond precision thanks to clock_gettime(CLOCK_REALTIME).  System.currentTimeMillis() already uses that, but it would be nice to not truncate the nanoseconds.  The situation on Mac OSX is not as good, since only gettimeofday() is available, which gives microseconds.  But it's still an improvement.

Of course on Windows all timing information between the 10ms granularity is quasi-fictional, but for figuring out order-of-events in a log, a "high-resolution clock simulator" on windows would still be useful.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
System.currentTimeNanos() would return a two-element long array containing {seconds, nanos} since epoch.  The time returned would be as accurate as the operating system could provide (e.g. nanos would be micros * 1000 on Mac OSX).

On Windows the time returned would be an approximation, since Windows cannot accurately report time changes faster than 10ms apart.

---------- BEGIN SOURCE ----------
Here is a prototype java library which illustrates the idea:

http://juliusdavies.ca/nanotime/

Download "nanotime.jar" and type:

java -jar nanotime.jar

It will print out 1 timing using System.currentTimeMillis(), and 10 timings using something like currentTimeNanos():

2008-05-14/17:08:15.940000000/PDT JavaTime
2008-05-14/17:08:15.940787900/PDT NativeTime
2008-05-14/17:08:15.943128363/PDT NativeTime
2008-05-14/17:08:15.943134021/PDT NativeTime
2008-05-14/17:08:15.943138875/PDT NativeTime
2008-05-14/17:08:15.943149498/PDT NativeTime
2008-05-14/17:08:15.943154580/PDT NativeTime
2008-05-14/17:08:15.943158845/PDT NativeTime
2008-05-14/17:08:15.943163060/PDT NativeTime
2008-05-14/17:08:15.943167074/PDT NativeTime
2008-05-14/17:08:15.943171148/PDT NativeTime

At this time the jar file can be run on Java 1.3, 1.4, 5, 6 on the following platforms:

linux-amd64 (includes intel 64bit x86, too)
linux-ppc (IBM's JDK)
linux-x86
mac-x86
solaris-sparc
win32


You need write-permission to ${user.home} to run this jar file.  It automatically extracts a native library to ${user.home}/.libjnt/ for the current platform.


Here is the JNI C code that asks the Operating System for the current time:

http://juliusdavies.ca/nanotime/src/native/mac_nano.c
http://juliusdavies.ca/nanotime/src/native/unix_nano.c
http://juliusdavies.ca/nanotime/src/native/win_nano.c

---------- END SOURCE ----------

Comments
See also JDK-8185891.
22-05-2018

It is also mandatory that currentTimeMillis() is based on a time-of-day clock. I'm trying to recall if there is a reason we can't switch to clock_gettime(CLOCK_REALTIME) instead of gettimeofday()
22-05-2018

JDK-8068730 added a mechanism to get (potentially) nano second precision for java.time, by making it possible to get a nanosecond time adjustment from the system (see http://hg.openjdk.java.net/jdk9/jdk9/hotspot/rev/fca33371ff0b) - but the precision is actually limited to microseconds due to the fact that the underlying implementation uses gettimeofday() which is *the same* clock that System::currentTimeMillis is using behind the hood. I guess it could be possible to change the implementation to use a more precise native clock, if such a clock was available, but then both java.time and System::currentTimeMillis would need to be changed to use that *same* clock, as it is mandatory that they are kept consistent with each other.
22-05-2018

Thanks! the API became available in java 8, albeit with only millisecond resolution, but jdk 9 gave us sub-millisecond resolution. Perhaps next decade we will get sub-microsecond resolution?! import java.time.Instant; /** Prints resolution of Instant. */ public class InstantResolution { public static void main(String[] args) { for (int prev = Instant.now().getNano(), jumps = 0; jumps < 10;) { int nanos = Instant.now().getNano(); if (nanos > prev) { System.out.println(nanos - prev); jumps++; } prev = nanos; } } } jdk 8: 1000000 4000000 1000000 1000000 1000000 1000000 1000000 1000000 1000000 1000000 jdk 9: 7000 242000 92000 71000 45000 42000 41000 41000 43000 43000
19-05-2018

JSR-310 was integrated in Java 8. It provides java.time.Instant.now() which returns an Instant containing seconds since epoch and nanosecond-of-second. It already has methods for time comparison, arithmetic, conversion, etc. and is thus preferable to an API that returns a bare array of these values. Closing as Not an Issue.
20-07-2017

EVALUATION The current request seems to be a more simple suggestion of exposing clock_gettime(CLOCK_REALTIME,...) through this new method. This does have high-resolution on modern Linux and Solaris systems - a few microseconds. But older Linuxes (and possibly Solaris) and Windows would still be limited to a value updated ~10ms. I don't see a reason to return an array however as a long can hold enough nanoseconds to represent 292+ years. The method would have to be fairly loosely specified to accommodate platform differences. We also don't know how well clock_gettime tracks TOD changes (ntp, DST etc), or how well behaved it is on MP systems.
25-06-2008

EVALUATION Unformtunately no conclusion was reached about what the actual requirements were for a function like currentTimeNanos().
24-06-2008

EVALUATION A discussion of this presise question may be found here: http://www.nabble.com/High-resolution-timers-and-JSR-310-td17302683.html David Holmes' response from May 18, 2008; 03:04pm is particularly enlightening. Also worth reading are the following two bugs: 6380553 provide precise SystemCurrentTimeMillis() based on System.nanoTime() 6298653 Use finest granularity clock (System.nanoTime) for sleep, wait, util.Timer ...
23-06-2008