Yerriswamy Manchi
Yerriswamy Manchi

Reputation: 51

How to achieve exact nanosecond precision using Date API in Java 8

We are trying to get exact nanoSeconds with 9 precision values for capturing Time.

Using Java 8 we can able to achieve as mentioned below.

@Test
public void testNanoClock() throws InterruptedException{
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
              .appendInstant(9).toFormatter();
       for (int i=0; i<10; i++) {
       final Clock clock = new NanoClock();
       log.info(formatter.format(clock.instant()));
       Thread.sleep(200);
       }
}

Overriden instant method as below

@Override
public Instant instant() {
  return initialInstant.plusNanos(getSystemNanos() - initialNanos);
}

And the complete implementation of the class is given below.

public class NanoClock extends Clock {

    private final Clock clock;

    private final long initialNanos;

    private final Instant initialInstant;

    public NanoClock() {
        this(Clock.systemUTC());
    }

    public NanoClock(final Clock clock) {
        this.clock = clock;
        initialInstant = clock.instant();
        initialNanos = getSystemNanos();
    }

    @Override
    public ZoneId getZone() {
        return clock.getZone();
    }

    @Override
    public Clock withZone(ZoneId zone) {
        return new NanoClock(clock.withZone(zone));
    }

    @Override
    public Instant instant() {
        return initialInstant.plusNanos(getSystemNanos() - initialNanos);
    }

    private long getSystemNanos() {
        return System.nanoTime();
    }
}

By using above code we are able to achieve time with nanosecond along 9 precision value:

2017-10-08T16:45:45.232000378Z

but in this case micro seconds are coming as 0's(zeros).

How can we achieve exact nanoSeconds time along with 9 precision values without 0's(zeros)? how does it workout?

Upvotes: 3

Views: 499

Answers (1)

JodaStephen
JodaStephen

Reputation: 63395

Your code creates a new instance of NanoClock within the loop. This resets the initialInstant and initialNanos each time, thus you never get to see the effect of the nanos. To make this work at all, you need to move the clock outside of the loop, potentially to a static constant.

You should also be aware that over time, this clock may deviate from real time, as System.currentTimeMillis() and System.nanoTime() are derived from different clock sources in the operating system, and are intended for different purposes (the former is calendar date/wall time, the latter is elapsed time). As such, you are actually measuring the elapsed time since the clock is created (over the course of a day, there may be some deviation between the two).

Upvotes: 4

Related Questions