Java 8 Instant.now() 具有纳秒级分辨率?

2022-09-01 09:31:36

Java 8的java.time.Instant以“纳秒分辨率”存储,但使用Instant.now()只能提供毫秒级分辨率...

Instant instant = Instant.now();
System.out.println(instant);
System.out.println(instant.getNano());

结果。。。

2013-12-19T18:22:39.639Z
639000000

如何获得值为“现在”但分辨率为“现在”的即时?


答案 1

虽然缺省的 Java8 时钟不提供纳秒分辨率,但您可以将其与 Java 功能结合使用,以纳秒分辨率测量时差,从而创建一个实际的纳秒级时钟。

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 Instant instant()
    {
        return initialInstant.plusNanos(getSystemNanos() - initialNanos);
    }

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

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

使用它很简单:只需向Instant.now()提供额外的参数,或直接调用Clock.instant():

    final Clock clock = new NanoClock();   
    final Instant instant = Instant.now(clock);
    System.out.println(instant);
    System.out.println(instant.getNano());

尽管即使您每次都重新创建 NanoClock 实例,此解决方案也可能有效,但最好始终坚持在代码早期初始化存储时钟,然后在需要的地方使用。


答案 2

如果您获得甚至毫秒级的分辨率,则可以认为自己很幸运。

Instant可以将时间建模为纳秒级精度,但至于实际分辨率,则取决于底层操作系统的实现。例如,在Windows上,分辨率非常低,约为10毫秒。

将其与 进行比较,后者以微秒为单位给出分辨率,但不给出绝对的挂钟时间。显然,已经有一个权衡在起作用,给你这种分辨率,仍然比纳秒短三个数量级。System.nanoTime()


推荐