java - 如何在 Java 8 中使用 Date API 实现精确的纳秒级精度

标签 java java-8 java-time

我们正在尝试获得具有 9 个精度值的精确纳秒以捕获时间。

使用 Java 8 我们可以实现如下所述。

@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);
       }
}

如下重写instant方法

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

下面给出了该类的完整实现。

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();
    }
}

通过使用上面的代码,我们能够实现纳秒级和 9 精度值的时间:

2017-10-08T16:45:45.232000378Z

但在这种情况下,微秒将以 0(零)的形式出现。

我们如何才能获得精确的纳秒级时间以及 9 个没有 0(零)的精度值?它是如何锻炼的?

最佳答案

您的代码在循环中创建了一个新的 NanoClock 实例。这每次都会重置 initialInstantinitialNanos,因此您永远看不到纳米的效果。要使这项工作完全正常,您需要将时钟移出循环,可能移至静态常量。

您还应注意,随着时间的推移,此时钟可能会偏离实际时间,因为 System.currentTimeMillis()System.nanoTime() 来自不同的时间操作系统中的时钟源,并且用于不同的目的(前者是日历日期/墙上时间,后者是耗时)。因此,您实际上是在测量自创建时钟以来耗时(在一天的过程中,两者之间可能存在一些偏差)。

关于java - 如何在 Java 8 中使用 Date API 实现精确的纳秒级精度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46649059/

相关文章:

java - 从 ListView 中将 DateFormat 转换为小时和分钟

java - 使用Java Server Pages,提交后如何制作 "register"表单数据

java - 为什么 jsonParser.getCodec().readTree(jsonParser).asText() 为我返回一个空字符串?

java - 做一个API,构造函数仅供系统私有(private)使用,另一个官方的,javadoc'ed和公共(public)使用的。关于修复/模式方法的建议

java - 如何使用 java 8 流从 HashMap 中获取值

java - 解析日期的优雅解决方案

java - 在多个字段上使用 groupingBy 条件后获取计数

java - 使用 StreamAPI 按多个字段查找总和、平均分组

java - 如何在 Java 中解析自定义的多种日期格式

java - 将日期和时间字符串解析为 ZonedDateTime 对象