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

use*_*355 19 java time nanotime

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

Instant instant = Instant.now();
System.out.println(instant);
System.out.println(instant.getNano());
Run Code Online (Sandbox Code Playgroud)

结果...

2013-12-19T18:22:39.639Z
639000000
Run Code Online (Sandbox Code Playgroud)

我怎样才能获得一个"现在"值但具有纳秒分辨率的瞬间?

log*_*two 15

虽然默认的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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

    final Clock clock = new NanoClock();   
    final Instant instant = Instant.now(clock);
    System.out.println(instant);
    System.out.println(instant.getNano());
Run Code Online (Sandbox Code Playgroud)

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

  • `System.nanoTime()`javadoc:`连续调用的差异超过大约292年(263纳秒)将无法正确计算由于数字溢出而耗尽的时间.看起来我将无法将它用于我的深空探险家;) (3认同)
  • 代码非常好。然而,这个前提存在严重缺陷。正如对其他答案的其他评论中所说,精确度与准确性不同。该代码将违反其运行的几乎所有硬件上的合同。 (2认同)
  • 这比返回纳秒的随机数更好,因为纳秒不代表实际时间?在我看来,要使其有用,您需要使用 NTP 或 PTP 通过网络将其同步到某个标准时钟。 (2认同)

Mar*_*nik 14

如果你的分辨率达到毫秒级,你可以认为自己很幸运.

Instant可以将时间建模为纳秒精度,但是计算机上跟踪挂钟时间的实际设备通常具有大约10毫秒的分辨率,并且几乎可以确定准确度相当于100毫秒(100毫秒将是一个乐观的假设).

将其与此相比较System.nanoTime(),它以微秒为单位给出分辨率,但不提供绝对的挂钟时间.很明显,在工作中已经有了权衡,可以给你那种分辨率,仍然是三个数量级的纳秒.

  • @TedHopp Javadoc中没有这种区别,这是唯一可以指定任何精度的地方.您可以将Javadoc读作"我们没有为测量指定任何精度","我们指定1 ns的隐含精度",甚至"我们甚至通过触及术语*精度*搞砸了".请你选择,但我坚持认为,在这里编写与Java相关的答案时,参考文档中使用的术语是最佳选择. (3认同)
  • 准确性和分辨率几乎不是同义词.您可以始终获得更高的分辨率,即精度(或更好,不确定性). (2认同)
  • 好吧,我几乎不会使用 Java 文档作为计量术语的权威。他们可能在 _repeatability_ 的意义上使用 _precision_,但更有可能的是,他们试图指出以纳秒为单位的报告时间是一种[错误精度](https://en.wikipedia.org/wiki/False_precision) )。 (2认同)

Men*_*ild 7

您只能通过使用 Instant-method 使用另一个更精确的 java.time.Clock 来获得具有“纳秒”的 Instantpublic static Instant now(Clock clock)在您的示例中,默认时钟通常使用 System.currentTimeMillis() ,它无法显示任何纳秒。

请注意,没有可用纳秒分辨率(实时)的时钟。java.time.Instant 的内部纳秒表示设施主要是由于需要映射以纳秒精度给出的数据库时间戳(但通常不精确到纳秒!)。

2015 年12 月 29 日更新: Java-9 将提供更好的时钟,请参阅我的新帖子


Sto*_*wke 5

因此,我花了一些时间在这里浏览Javadoc:

http://download.java.net/jdk8/docs/api/java/time/Instant.html

看来您应该能够执行以下操作:

Instant inst = Instant.now();
long time = inst.getEpochSecond();
time *= 1000000000l; //convert to nanoseconds
time += inst.getNano(); //the nanoseconds returned by inst.getNano() are the nanoseconds past the second so they need to be added to the epoch second
Run Code Online (Sandbox Code Playgroud)

就是说-其他答复者指出,要获得准确的纳秒级时间将非常困难,因为计算机通常没有能力跟踪达到该分辨率的时间