Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 355
SomeGuy Avatar asked Sep 18 '25 07:09

SomeGuy


1 Answers

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. In some implementations, that starting point may be when the host machine booted, but you cannot depend on that.

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?

  • Java SE 8, Java SE 9, and later
  • Built-in.
  • Part of the standard Java API with a bundled implementation.
  • Java 9 adds some minor features and fixes.
  • Java SE 6 and Java SE 7
  • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android
  • Later versions of Android bundle implementations of the java.time classes.
  • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

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.

like image 185
Basil Bourque Avatar answered Sep 19 '25 19:09

Basil Bourque