如何在Java中以纳秒为单位获取当前时间?

时间:2018-08-29 12:09:16

标签: java datetime influxdb

我做了很多研究,但没有找到任何好的答案。 我想以纳秒为单位获取当前日期和时间。 我发现System.nanoTime()将提供十亿分之一秒,但这是系统耗时。表示它将在系统启动时提供时间。我需要使用当前的日期和时间(以纳秒为单位)。

我需要这样做以避免InfluxDB中的点重复,请参阅How does InfluxDB handle duplicate points?。因此,当我使用毫秒时,我面临数据联合的问题。因此需要决定使用纳秒级,但问题是使用System.nanoTime()生成纳秒级时不包含当前日期和时间数据。它使我的JVM正常运行时间对我来说毫无用处。

3 个答案:

答案 0 :(得分:4)

理论上,可以使当前时间达到纳秒精度,如下所示:

Clock clock = Clock.systemDefaultZone();
Instant instant = clock.instant();   // or Instant.now();
long seconds = instant.getEpochSecond();
long nano = instant.getNano();
// epoch nanoseconds = seconds * 10E9 + nano

问题:

  1. systemDefaultZone()调用提供平台的“最佳可用时钟”。 JVM规范说这可能比毫秒精度要好,但这不能保证。因此,nano值的精度可能不超过毫秒。

  2. 秒和纳秒的值取决于本地硬件时钟的精度。在许多系统上,很难将本地时钟同步到“实时”。通常,亚毫秒级的精度具有挑战性,而明显的纳秒级精度是一种幻想。

  3. 即使您已经成功地将具有“实时”时间的硬件时钟同步到纳秒精度,进行上述调用以获取纪元纳秒时间的开销和可变性也会破坏纳秒精度。 (诸如内存缓存可变性,主内存总线的繁忙程度等。以及自上次同步以来本地硬件时钟的漂移。)

实际上,在大多数系统上,纳秒精度是无法实现的,因此您需要避免依赖于此的设计/算法。

答案 1 :(得分:0)

您可以从Instant.now()获得Java可以提供的最佳精度和精确度。我不敢说这是否足以解决您的问题。当然,在普通计算机上,无法获得纳秒精度。

Instant.now()返回相同值两次的情况下,您可能需要增加一些人造纳秒的技巧。

或者简单地使用your link中提到的技巧:

  

引入一个任意的新标签以强制唯一性。

例如,对于添加人工纳秒的技巧,您可以使用类似以下的内容:

public class TimeProvider {

    Instant last = Instant.now().minusSeconds(1);

    Instant getUniqueInstant() {
        Instant result = Instant.now();
        if (! result.isAfter(last)) {
            result = last.plusNanos(1);
        }
        last = result;
        return result;
    }
}

当我从计算机上的此类班级中快速连续绘制时间时,得到的结果如下。从输出(我的解释方式)看来:

  • 我的JVM从系统时钟获得的精度不能超过微秒(秒为6位小数)。
  • 现在会添加一个人造的纳秒级,以保持瞬间的独特性。

2018-08-29T15:18:35.617616001Z
2018-08-29T15:18:35.617617Z
2018-08-29T15:18:35.617618Z
2018-08-29T15:18:35.617618001Z
2018-08-29T15:18:35.617619Z
2018-08-29T15:18:35.617619001Z
2018-08-29T15:18:35.617620Z
2018-08-29T15:18:35.617620001Z
2018-08-29T15:18:35.617621Z
2018-08-29T15:18:35.617621001Z
2018-08-29T15:18:35.617622Z
2018-08-29T15:18:35.617623Z
2018-08-29T15:18:35.617623001Z
2018-08-29T15:18:35.617624Z
2018-08-29T15:18:35.617624001Z
2018-08-29T15:18:35.617625Z
2018-08-29T15:18:35.617625001Z
2018-08-29T15:18:35.617626Z
2018-08-29T15:18:35.617626001Z
2018-08-29T15:18:35.617627Z
2018-08-29T15:18:35.617627001Z
2018-08-29T15:18:35.617628Z
2018-08-29T15:18:35.617631Z
2018-08-29T15:18:35.617634Z
2018-08-29T15:18:35.617635Z
2018-08-29T15:18:35.617636Z
2018-08-29T15:18:35.617636001Z
2018-08-29T15:18:35.617637Z
2018-08-29T15:18:35.617637001Z
2018-08-29T15:18:35.617638Z

答案 2 :(得分:0)

最后,谢谢弗朗兹·威廉·肖特先生

我找到了一个解决方案。使用http://jenetics.io/和 类调用NanoClock.java正在转换,并且执行与Stephen C建议的相同的技巧。我想分享这一点,因为它也会对其他人有用。我无法确认是否指定了精确的纳米时间,但是这个技巧对我有用。 @Ole V.V.再次感谢您的帮助。