¿Cómo convertir nanosegundos a segundos usando la enumeración TimeUnit?

145

¿Cómo convertir un valor de nanosegundos a segundos?

Aquí está el segmento de código:

import java.io.*;
import java.util.concurrent.*; 
..

class Stamper { 

public static void main (String[] args) { 
long start = System.nanoTime(); 
//some try with nested loops 
long end = System.nanoTime(); 
long elapsedTime = end - start;

System.out.println("elapsed: " + elapsedTime + "nano seconds\n");

//convert to seconds 
TimeUnit seconds = new TimeUnit(); 
System.out.println("which is " + seconds.toSeconds(elapsedTime) + " seconds"); 
}}

El error es

Stamper.java:16:  enum types may not be instantiated.

¿Qué significa esto?

phill
fuente
44
El error significa que no puede crear una instancia del tipo TimeUtil, porque es un enum(enumerador). Si desea usar TimeUnit, debe usar TimeUnit.NANOSECONDS.toSeconds(elapsedTime)en su lugar. ¡Buena suerte!
Daniel Kvist

Respuestas:

200

Bueno, podrías dividir entre 1,000,000,000:

long elapsedTime = end - start;
double seconds = (double)elapsedTime / 1_000_000_000.0;

Si usa TimeUnitpara convertir, obtendrá su resultado como un largo, por lo que perderá la precisión decimal pero mantendrá la precisión del número entero.

Adam Rosenfield
fuente
78
Pero, ¿qué pasa si cambia el número de nanosegundos en un segundo? : P
geofftnz
9
Esta respuesta ahora es incorrecta, convert()y toFoo()todos los métodos devuelven longahora docs.oracle.com/javase/6/docs/api/java/util/concurrent/…
Riking
3
@mbarrows Sin embargo, esta respuesta sigue siendo correcta, ya que la TimeUnitsolución resulta en una pérdida de especificidad. TimeUnit.SECONDS.convert(500, TimeUnit.MILLISECONDS);Volveremos 0, no 0.5. Simplemente depende de su caso de uso cuál de estos es preferible.
nbrooks
17
Totalmente de acuerdo con @nbrooks aquí. El uso de TimeUnit no generará fracciones de segundo, sino que devolverá 0. Si no desea utilizar un número de 10 dígitos codificado, utilice algo como 1E9. Por ejemplo: double seconds = ((double) nanoseconds) / 1E9; haría esto cada vez como una preferencia personal.
TechTrip
3
Use este método sobre el método TimeUnit Enum si desea fracciones de segundo. El uso de TimeUnit Enum ni siquiera se redondea al segundo más cercano, esencialmente solo corta las fracciones de un segundo. Entonces 4.9999999, simplemente sería 4.
Dick Lucas
354

TimeUnit Enum

La siguiente expresión usa la TimeUnitenumeración (Java 5 y posterior) para convertir de nanosegundos a segundos:

TimeUnit.SECONDS.convert(elapsedTime, TimeUnit.NANOSECONDS)
pythonquick
fuente
14
No es que este método no incluya fracciones de segundo. Entonces 4.9999999, sería simplemente 4 segundos.
Dick Lucas
1
Esto se prefiere porque nunca debe escribir 1 seguido de un desorden completo de 0 debido a que es muy propenso a errores.
demongolem
1
puedes escribirlo así elapsedTime = (end_time - start_time) / 1e9;
Hasson
1
Si me quedo 59 minutos y 50 segundos, todavía dice 0h transcurrido ... Lo cual no es lo ideal. Entonces, ¿hay alguna manera de hacer que este método funcione con fracciones?
user1156544
58

TimeUnit es una enumeración, por lo que no puede crear una nueva.

Lo siguiente convertirá 1000000000000ns a segundos.

TimeUnit.NANOSECONDS.toSeconds(1000000000000L);
Nick Veys
fuente
44
¡Creo que es 10e + 9 no 1e + 12!
Adam Arold el
8
Esta es una respuesta bastante tardía, pero el número en el ejemplo no es el número de nanos en un segundo, es solo un número para convertir. La idea es no tener que conocer esos valores.
Nick Veys
2
Creo que esta debería ser la respuesta aceptada. Usar toXxx () es preferible a usar convert () porque con convert () no es obvio en qué dirección ocurre la conversión, mientras que con toXxx () es.
Klitos Kyriacou
21

Para reducir la verbosidad, puede usar una importación estática:

import static java.util.concurrent.TimeUnit.NANOSECONDS;

-y en adelante solo escriba

NANOSECONDS.toSeconds(elapsedTime);
Zoltán
fuente
6

Deberías escribir :

    long startTime = System.nanoTime();        
    long estimatedTime = System.nanoTime() - startTime;

Asignar el endTime en una variable puede causar unos pocos nanosegundos. En este enfoque, obtendrá el tiempo transcurrido exacto.

Y entonces:

TimeUnit.SECONDS.convert(estimatedTime, TimeUnit.NANOSECONDS)
Lalit Narayan Mishra
fuente
4

Esto convertirá un tiempo a segundos en un formato doble, que es más preciso que un valor entero:

double elapsedTimeInSeconds = TimeUnit.MILLISECONDS.convert(elapsedTime, TimeUnit.NANOSECONDS) / 1000.0;
Ayaz Alifov
fuente