Heure actuelle en microsecondes en java

sur un système Unix, y a-t-il un moyen d'obtenir un timestamp avec une précision de niveau microseconde en Java? Quelque chose comme la fonction gettimeofday de C.

90
demandé sur bluish 2009-11-11 03:25:39

10 réponses

Non, Java n'a pas cette capacité.

il a un système.nanoTime(), mais qui donne juste un décalage de certains déjà connus du temps. Donc, même si vous ne pouvez pas prendre le nombre absolu à partir de cela, vous pouvez l'utiliser pour mesurer la précision nanoseconde (ou plus).

notez que le JavaDoc dit que bien que cela fournisse une précision de nanoseconde, cela ne signifie pas une précision de nanoseconde. Prenez donc suffisamment grand module de la valeur de retour.

130
répondu AlBlue 2018-09-11 18:01:07

vous pouvez utiliser System.nanoTime() :

long start = System.nanoTime();
// do stuff
long end = System.nanoTime();
long microseconds = (end - start) / 1000;

pour obtenir le temps en nanosecondes mais c'est une mesure strictement relative. Il n'a pas de signification absolue. Il est seulement utile pour comparer à d'autres nano fois pour mesurer combien de temps quelque chose a faire.

52
répondu cletus 2011-08-17 14:14:25

tl; dr

Java 9 et plus tard: Jusqu'à nanosecondes résolution lors de la capture de l'instant actuel. C'est 9 chiffres de fraction décimale.

Instant.now()   

2017-12-23T12: 34 :56.123456789 Z

pour limiter aux microsecondes, tronquer.

Instant.now().truncatedTo( ChronoUnit.MICROSECONDS );

2017-12-23T12: 34 :56.123456 Z

détails

les autres réponses sont quelque peu périmées depuis Java 8.

de java.time

Java 8 et plus tard vient avec le java.temps cadre de. Ces nouvelles classes remplacent les classes de date-heure défectueuses livrées avec les premières versions de Java telles que java.util.Date./Calendrier et java.texte.SimpleDateFormat. Le cadre est défini par JSR 310, inspiré par Joda-Time , prolongé par le ThreeTen-Extra project.

les classes en java.le temps de résoudre à nanosecondes , beaucoup plus fine que la millisecondes utilisé par les vieux date du temps des classes et par Joda-Time. Et plus fin que le microsecondes posé dans la Question.

enter image description here

Clock mise en Œuvre

pendant la java.les classes de temps prennent en charge les données représentant les valeurs en nanosecondes, les classes ne génèrent pas encore les valeurs en nanosecondes. Les méthodes now() utilisent la même ancienne implémentation d'horloge que les anciennes classes de date-heure., System.currentTimeMillis() . Nous avons la nouvelle interface Clock en java.le temps mais l'implémentation pour cette interface est la même vieille horloge de millisecondes.

pour que vous puissiez formater le représentation textuelle du résultat de ZonedDateTime.now( ZoneId.of( "America/Montreal" ) ) pour voir neuf chiffres d'une fraction de seconde mais seulement les trois premiers chiffres auront des nombres comme ceci:

2017-12-23T12:34:56.789000000Z

Nouvelle Horloge En Java 9

les implémentations OpenJDK et Oracle de Java 9 ont une nouvelle implémentation par défaut Clock avec une granularité plus fine, jusqu'à la pleine capacité nanoseconde de java.les classes de temps.

Voir l'OpenJDK question, Augmenter la précision de la mise en œuvre de java.temps.Horloge.systemUTC () . Ce problème a été mis en œuvre avec succès.

2017-12-23T12:34:56.123456789Z

sur un MacBook Pro (rétine, 15 pouces, fin 2013) avec macOS Sierra, je reçois le moment actuel en microsecondes (jusqu'à six chiffres de fraction décimale).

2017-12-23T12:34:56.123456Z

Horloge Matérielle

rappelez-vous que même avec une nouvelle implémentation plus fine Clock , vos résultats peuvent varier d'un ordinateur à l'autre. Java dépend de l'horloge du matériel informatique sous-jacent pour connaître le moment présent.

  • la résolution des horloges matérielles varient considérablement. Par exemple, si l'horloge matérielle d'un ordinateur particulier ne supporte que microsecondes granularité, toute valeur de date-heure générée aura seulement six chiffres de fraction de seconde avec les trois derniers chiffres étant des zéros.
  • la précision des horloges matérielles varient considérablement. Juste parce qu'une horloge génère une valeur avec plusieurs chiffres de fraction décimale d'une seconde, ces chiffres peuvent être imprécis, juste des approximations, à la dérive de l'heure réelle comme pourrait être lu à partir d'une horloge atomique . En d'autres termes, juste parce que vous voyez un tas de chiffres à la droite de la marque décimale ne signifie pas que vous pouvez faire confiance au temps écoulé entre de telles lectures pour être vrai à ce degré minute.
52
répondu Basil Bourque 2018-04-04 21:21:59

comme d'autres posters l'ont déjà indiqué; votre horloge système n'est probablement pas synchronisée jusqu'à microsecondes avec l'heure réelle du monde. Néanmoins, les chronomètres de précision microsecondes sont utiles en tant qu'hybride à la fois pour indiquer le temps de paroi actuel et pour mesurer/profiler la durée des choses.

je l'étiquette de tous les événements, les messages écrits dans un journal de fichiers à l'aide des horodateurs, comme "2012-10-21 19:13:45.267128". Ceux-ci véhiculent à la fois quand il s'est produit ("Mur" Temps), et peut également être utilisé pour mesurer la durée entre cet événement et le suivant dans le fichier log (différence relative en microsecondes).

pour ce faire, vous devez relier le système.currentTimeMillis () avec System.nanoTime() et travaille exclusivement avec System.nanoTime() à partir de ce moment-là. Exemple de code:

/**
 * Class to generate timestamps with microsecond precision
 * For example: MicroTimestamp.INSTANCE.get() = "2012-10-21 19:13:45.267128"
 */ 
public enum MicroTimestamp 
{  INSTANCE ;

   private long              startDate ;
   private long              startNanoseconds ;
   private SimpleDateFormat  dateFormat ;

   private MicroTimestamp()
   {  this.startDate = System.currentTimeMillis() ;
      this.startNanoseconds = System.nanoTime() ;
      this.dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS") ;
   }

   public String get()
   {  long microSeconds = (System.nanoTime() - this.startNanoseconds) / 1000 ;
      long date = this.startDate + (microSeconds/1000) ;
      return this.dateFormat.format(date) + String.format("%03d", microSeconds % 1000) ;
   }
}
13
répondu Jason Smith 2012-10-21 20:03:57

si vous êtes intéressé par Linux: Si vous épluchez le code source de "currentTimeMillis()", vous verrez que, sur Linux, si vous appelez cette méthode, elle obtient un temps de microseconde en arrière. Cependant, Java tronque ensuite les microsecondes et vous renvoie des millisecondes. Cela s'explique en partie par le fait que Java doit être une plate-forme croisée, de sorte que fournir des méthodes spécifiquement pour Linux était un grand non-pas à l'époque (rappelez-vous que le support de liens mous cruddy de 1.6 à l'envers?!). C'est aussi parce que, pendant que vous chronométrez peut vous donner en retour des microsecondes sous Linux, cela ne signifie pas nécessairement qu'il sera bon de vérifier l'heure. Au niveau de la microseconde, vous devez savoir que le NTP ne réaligne pas votre temps et que votre horloge n'a pas trop dérivé pendant les appels de méthode.

cela signifie, en théorie, que sur Linux, vous pouvez écrire un wrapper JNI qui est le même que celui du paquet système, mais qui ne tronque pas les microsecondes.

2
répondu Badgerous 2014-12-31 17:14:37

un "rapide et sale" la solution que j'ai finalement fait avec:

TimeUnit.NANOSECONDS.toMicros(System.nanoTime());

mise à jour:

j'ai utilisé le système à l'origine.nanoTime mais ensuite j'ai découvert qu'il ne devait être utilisé que pour le temps écoulé, j'ai finalement changé mon code pour travailler avec des millisecondes ou à certains endroits utiliser:

TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis());

mais cela ajoutera juste des zéros à la fin de la valeur (micros = millidis * 1000)

a laissé cette réponse ici comme un "signe d'alerte" dans le cas où quelqu'un d'autre pense de nanoTime :)

2
répondu keisar 2015-11-03 05:32:20

Java support microsecondes à travers TimeUnit enum.

voici le doc java: Enum TimeUnit

vous pouvez obtenir des microsecondes en java de cette façon:

long microsenconds = TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis());

vous pouvez également convertir des microsecondes à d'autres unités de temps, par exemple:

long seconds = TimeUnit.MICROSECONDS.toSeconds(microsenconds);
1
répondu tanghao 2016-09-24 23:57:56

si vous avez l'intention de l'utiliser pour le système en temps réel, peut-être que java n'est pas le meilleur choix pour obtenir l'horodatage. Mais si vous allez utiliser si pour la clé unique, alors la réponse de Jason Smith en fera assez. Mais juste au cas où, pour anticiper 2 item finissent par obtenir le même timestamp (c'est possible si ces 2 ont été traités presque simultanément), vous pouvez boucler jusqu'à ce que le dernier timestamp n'égale pas avec le timestamp actuel.

String timestamp = new String();
do {
    timestamp = String.valueOf(MicroTimestamp.INSTANCE.get());
    item.setTimestamp(timestamp);
} while(lasttimestamp.equals(timestamp));
lasttimestamp = item.getTimestamp();
0
répondu wingedcrown 2014-10-26 22:59:22

vous pourriez peut-être créer un composant qui détermine le décalage entre les systèmes.nanoTime() et du Système.currentTimeMillis() et efficacement obtenir de nanosecondes depuis l'époque.

public class TimerImpl implements Timer {

    private final long offset;

    private static long calculateOffset() {
        final long nano = System.nanoTime();
        final long nanoFromMilli = System.currentTimeMillis() * 1_000_000;
        return nanoFromMilli - nano;
    }

    public TimerImpl() {
        final int count = 500;
        BigDecimal offsetSum = BigDecimal.ZERO;
        for (int i = 0; i < count; i++) {
            offsetSum = offsetSum.add(BigDecimal.valueOf(calculateOffset()));
        }
        offset = (offsetSum.divide(BigDecimal.valueOf(count))).longValue();
    }

    public long nowNano() {
        return offset + System.nanoTime();
    }

    public long nowMicro() {
        return (offset + System.nanoTime()) / 1000;
    }

    public long nowMilli() {
        return System.currentTimeMillis();
    }
}

après le test produit des résultats assez bons sur ma machine.

    final Timer timer = new TimerImpl();
    while (true) {
        System.out.println(timer.nowNano());
        System.out.println(timer.nowMilli());
    }

la différence semble osciller dans la gamme de +-3ms. Je pense que l'on pourrait modifier un peu plus le calcul de l'offset.

1495065607202174413
1495065607203
1495065607202177574
1495065607203
...
1495065607372205730
1495065607370
1495065607372208890
1495065607370
...
0
répondu kangcz 2017-05-18 00:06:16

voici un exemple de la façon de créer une estampille de temps courante Non signée:

UnsignedLong current = new UnsignedLong(new Timestamp(new Date().getTime()).getTime());
-3
répondu thefourtheye 2014-09-18 13:15:06