简体   繁体   中英

Nanosecond Time in Java Without Using java.util.Date

I have the need for extremely precise and accurate time with as few garbage collections (GCs) as possible, ideally 1 per day. System.currentTimeMillis() is not precise enough, System.nanoTime() isn't an accurate source of time. The only thing that will give me what I want is java.util.Date.getTime() but it's not a static method so I have to create a new Date object every time I need precise and accurate time which causes GC to be triggered more often.

Does anyone know how the Date class gets accurate and precise time? I'm hoping to take Date's method and tailor it to minimize object creation. To summarize my problem, see the following:

long nanosSinceEpoch;
nanosSinceEpoch = System.currentTimeMillis(); // Not precise
nanosSinceEpoch = System.nanoTime();          // Not accurate
nanosSinceEpoch = new Date().getTime();       // Too many objects

EDIT:

I'm not sure why I thought System.currentTimeMillis() and new Date().getTime() were different but it turns out they are the same. But that didn't fix my problem sadly.

Also, getNano() from java.time.Instant appears to only have millisecond resolution.

Instant.now

Java 9 brought a fresh implementation of Clock able to capture the current moment in a precision finer than the milliseconds capability of Java 8's Clock .

Instant instant = Instant.now() ;

Let me be clear: The Instant class in all versions of Java is able to hold a value in nanoseconds . But capturing the current moment is limited to milliseconds in Version 8 specifically.

You should research the capabilities of the hardware clock of your current computer equipment. I believe you will find that current conventional hardware is not capable of accuracy in tracking time to the nanosecond.

In using Oracle JDK 9.0.4 on macOS Sierra, I am seeing current moment captured in microseconds , six digits of decimal fractional second.

System.nanoTime() isn't an accurate source of time

No, accuracy is not the issue. The issue there is that System.nanoTime() is designed to track elapsed time , not the current date-time. This feature simply tracks a count of nanoseconds since an arbitrary undocumented starting point.

And again, as noted above, we are not talking about incrementing by single nanoseconds as current conventional computer hardware is not capable.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date , Calendar , & SimpleDateFormat .

The Joda-Time project, now in maintenance mode , advises migration to the java.time classes.

To learn more, see the Oracle Tutorial . And search Stack Overflow for many examples and explanations. Specification is JSR 310 .

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval , YearWeek , YearQuarter , and more .

System.nanoTime() isn't an accurate source of time

This is not quite true. Its accuracy is highly system-dependent . If you have control over your hardware and OS you can in principle construct a high precision clock from it even on older java versions.

Since JDK-8068730 has been implemented the newer time APIs shield you from those complexities by deferring to the most accurate OS clock available which in turn will do the necessary hardware feature detection to figure out whether the TSCs are reliable enough to be used as a time source.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM