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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32443254/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 20:11:46  来源:igfitidea点击:

How can I convert the result of System.nanoTime to a date in Java?

javadatenanotime

提问by Cel Skeggs

I want to convert the result of System.nanoTime()to a date.

我想将结果转换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 
}

I have converted the seconds into nanosecondsby multiplying by 10^9. Now I need to convert the current system time plus the parameter which I converted into nanoseconds into a date.

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

回答by Cel Skeggs

Unfortunately, System.nanoTime()is not what you want for this.

不幸的是,System.nanoTime()这不是你想要的。

To quote the JavaDoc:

引用 JavaDoc:

This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time. The value returned represents nanoseconds since some fixed but arbitrary origin time (perhaps in the future, so values may be negative). The same origin is used by all invocations of this method in an instance of a Java virtual machine; other virtual machine instances are likely to use a different origin.

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

You probably want System.currentTimeMillis(), in which case you can use new Date(System.currentTimeMillis() + milliseconds)to get the date for that number of milliseconds in the future.

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

While you could then subtract System.nanoTime(), scale the value, and add System.currentTimeMillis()to have a similar result... since you're adding System.nanoTime()anyway and therefore have the original number of seconds, you could just use System.currentTimeMillis()directly.

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

回答by Farhad Baghirov

In the theory, you should not use the only System.nanotime(), but you can do a simple trick with this method in order to get nanoseconds of the current time.

从理论上讲,您不应该使用唯一的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;

    }
}

Even though, you can create your own Clock implementation with this way for using high-level java data time classes.

尽管如此,您可以通过这种方式创建自己的时钟实现,以使用高级 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);
    }

}

Now we can use our clock implementation like the following:

现在我们可以使用我们的时钟实现,如下所示:

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

回答by Tom chan

You can convert it into system time using the below code

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

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

Explanation:

解释:

System.nonoTime() is a monotonic time that increases only, it has no idea of what time it is right now, but it would only increase regardless. So it is a good way for measuring elapsing time. But you can not convert this into a sensible time as it has no reference to the current time.

System.nonoTime() 是一个只会增加的单调时间,它不知道现在是什么时间,但无论如何它只会增加。因此,这是测量经过时间的好方法。但是您无法将其转换为合理的时间,因为它没有参考当前时间。

The provided method is a way to convert your stored nano time into a sensible time. First, you have a timeMs that is in nano time that you would like to convert. Then, you created another nanotime (i.e refMonoMs) and another System.currentTimeMillis() (i.e refUnixMx). Then you minus refMonoMs from the timeMs, and add the reference back into it to get the sensible time back.

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