11

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

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

4

3 回答 3

17

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

引用 JavaDoc:

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

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

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

于 2015-09-07T18:13:45.983 回答
3

从理论上讲,您不应该使用唯一的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
于 2020-04-04T15:27:35.877 回答
-4

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.

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.

于 2018-01-03T15:33:47.940 回答