Como converter nanossegundos em segundos usando a enumeração TimeUnit?

145

Como converter um valor de nanossegundos para segundos?

Aqui está o 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"); 
}}

O erro é

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

O que isto significa?

phill
fonte
4
O erro significa que você não pode instanciar o tipo TimeUtil, porque é um enum(enumerador). Se você deseja usar TimeUnit, você deve usá-lo TimeUnit.NANOSECONDS.toSeconds(elapsedTime). Boa sorte!
precisa

Respostas:

200

Bem, você pode dividir por 1.000.000.000:

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

Se você usar TimeUnita conversão, obterá o resultado por muito tempo, perdendo a precisão decimal, mas mantendo a precisão do número inteiro.

Adam Rosenfield
fonte
78
Mas e se o número de nanossegundos em um segundo mudar? : P
geofftnz
9
Agora, esta resposta está errada - convert()e toFoo()todos os métodos retornam longagora. Docs.oracle.com/javase/6/docs/api/java/util/concurrent/…
Riking
3
@mbarrows No entanto, esta resposta ainda está correta , pois a TimeUnitsolução resulta em uma perda de especificidade. TimeUnit.SECONDS.convert(500, TimeUnit.MILLISECONDS);retornará 0, não 0.5. Simplesmente depende do seu caso de uso qual deles é preferível.
N
17
Concordo plenamente com @nbrooks aqui. Usar TimeUnit não produzirá frações de segundo, retornando 0. Se você não quiser usar um número de 10 dígitos codificado, use algo como 1E9. Por exemplo: double seconds = ((double) nanoseconds) / 1E9; eu faria isso toda vez como uma preferência pessoal.
TechTrip 14/08/14
3
Use este método sobre o método TimeUnit Enum se desejar frações de segundo. O uso do TimeUnit Enum nem arredonda para o segundo mais próximo, basicamente apenas corta as frações de segundo. Então, 4.9999999, seria simplesmente 4.
Dick Lucas
354

TimeUnit Enum

A expressão a seguir usa a TimeUnitenumeração (Java 5 e posterior) para converter de nanossegundos para segundos:

TimeUnit.SECONDS.convert(elapsedTime, TimeUnit.NANOSECONDS)
pythonquick
fonte
14
Não que esse método não inclua frações de segundo. Então, 4.9999999, seria simplesmente 4 segundos.
Dick Lucas
1
Isso é preferível, porque você nunca deve escrever 1 seguido por uma bagunça de 0 devido a ser muito propenso a erros.
Demongolem
1
você pode escrevê-lo assim: elapsedTime = (end_time - start_time) / 1e9;
Hasson
1
Se eu ficar 59 minutos e 50 segundos, ele ainda diz que 0h passou ... O que não é o ideal. Existe alguma maneira de fazer esse método funcionar com frações?
user1156544
58

TimeUnit é uma enumeração, portanto você não pode criar uma nova.

A seguir, converteremos 1000000000000ns em segundos.

TimeUnit.NANOSECONDS.toSeconds(1000000000000L);
Nick Veys
fonte
4
Eu acredito que é 10e + 9 e não 1e + 12!
Adam Arold
8
Esta é uma resposta bastante tardia, mas o número no exemplo não é o número de nanos em um segundo, é apenas um número para converter. A idéia toda é não precisar conhecer esses valores.
22414 Nick Veys
2
Eu acho que essa deve ser a resposta aceita. Usar toXxx () é preferível a usar convert () porque com convert () não é óbvio em qual direção a conversão acontece, enquanto que com toXxx () é.
Klitos Kyriacou
21

Para reduzir a verbosidade, você pode usar uma importação estática:

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

-e doravante apenas digite

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

Você deve escrever:

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

Atribuir o endTime a uma variável pode causar alguns nanossegundos. Nesta abordagem, você obterá o tempo decorrido exato.

E depois:

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

Isso converterá um tempo para segundos em um formato duplo, mais preciso que um valor inteiro:

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