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を掛けて、秒を nanoseconds に変換しました。次に、現在のシステム時刻に加えて、ナノ秒に変換したパラメーターを日付に変換する必要があります。
残念ながら、 System.nanoTime()
はこれに必要なものではありません。
JavaDocを引用するには:
この方法は、経過時間を測定するためにのみ使用でき、システムや実時間のその他の概念とは関係ありません。返される値は、固定されているが任意の起点時刻からのナノ秒を表します(おそらく将来、値が負になる可能性があります)。 Java仮想マシン;他の仮想マシンインスタンスは異なるオリジンを使用する可能性が高いため、このメソッドのすべての呼び出しで同じオリジンが使用されます。
おそらく System.currentTimeMillis()
が必要です。この場合、new Date(System.currentTimeMillis() + milliseconds)
を使用して、将来のそのミリ秒数の日付を取得できます。
次に、System.nanoTime()
を減算し、値をスケーリングし、System.currentTimeMillis()
を追加して、同様の結果を得ることができます...とにかくSystem.nanoTime()
を追加しているため、元の秒数では、System.currentTimeMillis()
を直接使用できます。
理論的には、 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