如何将System.nanoTime的结果转换为Java中的日期?

时间:2015-09-07 17:00:46

标签: java date nanotime

我想将System.nanoTime()的结果转换为日期。

public void tempBan(Player p, Player banner, int timeInSeconds){
    Long timeInNano = (long) (timeInSeconds * 10^9);
    int newTime = (int) (System.nanoTime() + timeInNano);
    // here I want to convert newTime to a date 
}

我已经将秒数转换为nanoseconds乘以10 ^ 9。现在我需要将当前系统时间加上我转换为纳秒的参数转换为日期。

3 个答案:

答案 0 :(得分:11)

不幸的是,System.nanoTime()并不是您想要的。

引用JavaDoc:

  

此方法只能用于测量经过的时间,与系统或挂钟时间的任何其他概念无关。返回的值表示纳秒,因为某些固定但任意的原始时间(可能在未来,因此值可能为负)。在Java虚拟机的实例中,此方法的所有调用都使用相同的原点;其他虚拟机实例可能使用不同的来源。

您可能需要System.currentTimeMillis(),在这种情况下,您可以使用new Date(System.currentTimeMillis() + milliseconds)来获取将来该毫秒数的日期。

然后您可以减去System.nanoTime(),然后缩放该值,并添加System.currentTimeMillis()以获得类似的结果...因为您无论如何都要添加System.nanoTime()因此具有原始秒数,您可以直接使用System.currentTimeMillis()

答案 1 :(得分:1)

从理论上讲,您不应仅使用System.nanotime(),而是可以使用此方法做一个简单的技巧,以获取当前时间的纳秒。

public class TimeProvider{
    private final static long  jvm_diff;
    static {
        jvm_diff = System.currentTimeMillis()*1000_000-System.nanoTime();   
    }

    public static long getAccurateNow(){
        return System.nanoTime()+jvm_diff;

    }
}

尽管如此,您仍然可以使用这种方式创建自己的Clock实现,以使用高级Java数据时间类。

public class HighLevelClock extends Clock {

    private final ZoneId zoneId;

    public HighLevelClock(ZoneId zoneId) {
        this.zoneId = zoneId;
    }
    static long nano_per_second = 1000_000_000L;

    @Override
    public ZoneId getZone() {
        return zoneId;
    }

    @Override
    public Clock withZone(ZoneId zoneId) {
        return new HighLevelClock(zoneId);
    }

    @Override
    public Instant instant() {
        long nanos = TimeProvider.getAccurateNow();
        return Instant.ofEpochSecond(nanos/nano_per_second, nanos%nano_per_second);
    }

}

现在,我们可以像下面这样使用时钟实现:

Clock highLevelClock = new HighLevelClock(ZoneId.systemDefault());
System.out.println(LocalDateTime.now(highLevelClock));  //2020-04-04T19:22:06.756194290
System.out.println(ZonedDateTime.now(highLevelClock));  //2020-04-04T19:22:06.756202923+04:00[Asia/Baku]
System.out.println(LocalTime.now(highLevelClock));  //19:22:06.756220764

答案 2 :(得分:-3)

您可以使用以下代码将其转换为系统时间

public static long convertToUnixMs(final long timeMs) {
    final long refMonoMs = monoTimeMs();
    final long refUnixMx = System.currentTimeMillis();

    return refUnixMx + (timeMs - refMonoMs);
}
public static long monoTimeMs() {
        return System.nanoTime() / 1000000;
    }

说明:

System.nonoTime()是一个单调时间,只是增加,它不知道现在是什么时候,但它只会增加。所以这是测量流逝时间的好方法。但你无法将其转换为合理的时间,因为它没有参考当前时间。

提供的方法是将存储的纳米时间转换为合理时间的方法。首先,你有一个你希望转换的纳米时间的timeMs。然后,您创建了另一个纳米级(即refMonoMs)和另一个System.currentTimeMillis()(即refUnixMx)。然后你从timeMs减去refMonoMs,并将引用添加回来以获得合理的时间。