Comment convertir des nanosecondes en secondes à l'aide de l'énumération TimeUnit?

145

Comment convertir une valeur de nanosecondes en secondes?

Voici le segment de code:

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

L'erreur est

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

Qu'est-ce que ça veut dire?

Phill
la source
4
L'erreur signifie que vous ne pouvez pas instancier le type TimeUtil, car il s'agit d'un enum(énumérateur). Si vous souhaitez utiliser TimeUnit, vous devez utiliser à la TimeUnit.NANOSECONDS.toSeconds(elapsedTime)place. Bonne chance!
Daniel Kvist

Réponses:

200

Eh bien, vous pouvez simplement diviser par 1 000 000 000:

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

Si vous utilisez TimeUnitpour convertir, vous obtiendrez votre résultat sous forme de long, vous perdrez donc la précision décimale tout en conservant la précision des nombres entiers.

Adam Rosenfield
la source
78
Mais que faire si le nombre de nanosecondes dans une seconde change? : P
geofftnz
9
Cette réponse est maintenant fausse - convert()et les toFoo()méthodes retournent toutes longmaintenant docs.oracle.com/javase/6/docs/api/java/util/concurrent
...
3
@mbarrows Cependant cette réponse est toujours juste dans la mesure où la TimeUnitsolution se traduit par une perte de spécificité. TimeUnit.SECONDS.convert(500, TimeUnit.MILLISECONDS);reviendra 0, non 0.5. Cela dépend simplement de votre cas d'utilisation, lequel de ceux-ci est préférable.
nbrooks
17
Tout à fait d'accord avec @nbrooks ici. Utiliser TimeUnit ne produira pas de fractions de seconde, mais retournera 0. Si vous ne voulez pas utiliser un nombre à 10 chiffres codé en dur, utilisez quelque chose comme 1E9. Par exemple: double seconds = ((double) nanoseconds) / 1E9; je le ferais à chaque fois par préférence personnelle.
TechTrip
3
Utilisez cette méthode sur la méthode TimeUnit Enum si vous souhaitez des fractions de seconde. L'utilisation de TimeUnit Enum n'arrondit même pas à la seconde la plus proche, elle coupe essentiellement les fractions de seconde. Donc, 4,9999999, serait simplement 4.
Dick Lucas
354

TimeUnit Enum

L'expression suivante utilise l' TimeUniténumération (Java 5 et versions ultérieures) pour convertir des nanosecondes en secondes:

TimeUnit.SECONDS.convert(elapsedTime, TimeUnit.NANOSECONDS)
python rapide
la source
14
Non pas que cette méthode n'inclut pas les fractions de seconde. Donc, 4,9999999, serait simplement 4 secondes.
Dick Lucas
1
Ceci est préférable car vous ne devriez jamais écrire 1 suivi d'un désordre complet de 0 car il est très sujet aux erreurs.
demongolem
1
vous pouvez l'écrire comme ceci elapsedTime = (end_time - start_time) / 1e9;
Hasson
1
Si je reste 59 minutes et 50 secondes ça dit quand même 0h écoulé ... Ce qui n'est pas idéal. Alors, y a-t-il un moyen de faire fonctionner cette méthode avec des fractions?
user1156544
58

TimeUnit est une énumération, vous ne pouvez donc pas en créer une nouvelle.

Ce qui suit convertira 1000000000000ns en secondes.

TimeUnit.NANOSECONDS.toSeconds(1000000000000L);
Nick Veys
la source
4
Je crois que c'est 10e + 9 pas 1e + 12!
Adam Arold
8
C'est une réponse assez tardive, mais le nombre dans l'exemple n'est pas le nombre de nanos en une seconde, c'est juste un nombre à convertir. L'idée générale est de ne pas avoir à connaître ces valeurs.
Nick Veys
2
Je pense que cela devrait être la réponse acceptée. L'utilisation de toXxx () est préférable à l'utilisation de convert () car avec convert () il n'est pas évident de savoir dans quelle direction la conversion se produit, alors qu'avec toXxx () c'est le cas.
Klitos Kyriacou
21

Pour réduire la verbosité, vous pouvez utiliser une importation statique:

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

-et désormais tapez simplement

NANOSECONDS.toSeconds(elapsedTime);
Zoltán
la source
6

Vous devriez écrire:

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

L'affectation de endTime dans une variable peut entraîner quelques nanosecondes. Dans cette approche, vous obtiendrez le temps écoulé exact.

Puis:

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

Cela convertira une heure en secondes dans un format double, qui est plus précis qu'une valeur entière:

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