Comment mesurer le temps écoulé en Java? [dupliquer]


Cette question a déjà une réponse ici:

Je veux avoir quelque chose comme ceci:

public class Stream
{
    public startTime;
    public endTime;

    public getDuration()
    {
        return startTime - endTime;
    }
}

Il est également important que, par exemple, si l'heure de début est 23:00 et l'heure de fin 1:00 pour obtenir une durée de 2:00.

Quels types utiliser pour accomplir cela en Java?

Author: Mark Rotteveel, 2009-11-20

15 answers

Malheureusement, aucune des dix réponses publiées jusqu'à présent n'est tout à fait correcte.

Si vous mesurez le temps écoulé et que vous voulez qu'il soit correct, vous devez utiliser System.nanoTime(). Vous ne pouvez pas utiliser System.currentTimeMillis(), sauf si cela ne vous dérange pas que votre résultat soit erroné.

Le but de nanoTime est de mesure écoulé temps, et le but de currentTimeMillis est de mesure horloge murale temps. Vous ne pouvez pas utiliser l'un pour l'autre but. La raison en est qu'aucune horloge d'ordinateur n'est parfaite; il dérive toujours et doit parfois être corrigé. Cette correction peut se produire manuellement, ou dans le cas de la plupart des machines, il y a un processus qui s'exécute et émet continuellement de petites corrections à l'horloge système ("horloge murale"). Ceux-ci ont tendance à se produire souvent. Une autre correction de ce type se produit chaque fois qu'il y a une seconde bissextile.

Puisque le but de nanoTime est de mesurer le temps écoulé, il n'est affecté par aucune de ces petites corrections. C'est ce que vous voulez utiliser. Tous les horaires actuellement en cours avec currentTimeMillis sera éteint possibly peut-être même négatif.

Vous pouvez dire :" cela ne semble pas vraiment avoir autant d'importance", ce à quoi je dis, peut-être pas, mais dans l'ensemble, le code correct n'est-il pas meilleur que le code incorrect? De plus, nanoTime est plus court à taper de toute façon.

Les avis de non-responsabilité publiés précédemment concernant nanoTime n'ayant généralement qu'une précision de la microseconde sont valides. En outre, il peut prendre plus d'une microseconde entière à invoquer, selon les circonstances (tout comme l'autre), donc, ne vous attendez pas à temps très très petits intervalles correctement.

 577
Author: Kevin Bourrillion, 2009-11-21 17:07:21

Quels types utiliser pour accomplir cela en Java?

La réponse courte est un long. Maintenant, plus sur la façon de mesurer...

Système.currentTimeMillis()

La façon "traditionnelle" de le faire est en effet d'utiliser System.currentTimeMillis():

long startTime = System.currentTimeMillis();
// ... do something ...
long estimatedTime = System.currentTimeMillis() - startTime;

O. a. c. l. t. Chronomètre

Notez que Commons Lang a une classe StopWatch qui peut être utilisée pour mesurer le temps d'exécution en millisecondes. Il a des méthodes, les méthodes comme split(), suspend(), resume(), etc qui permettent de prendre des mesures en différents points de l'exécution et que vous pourriez trouver pratique. Avoir un coup d'oeil.

Système.nanoTime()

Vous pouvez préférer utiliser System.nanoTime() si vous recherchez des mesures extrêmement précises du temps écoulé. De son javadoc:

long startTime = System.nanoTime();    
// ... the code being measured ...    
long estimatedTime = System.nanoTime() - startTime;

Jamon

Une Autre option serait d'utiliser JAMon, un outil qui rassemble statistique (temps d'exécution, le nombre de hit, temps d'exécution moyen, min, max, etc.) pour tout code qui se situe entre les méthodes start() et stop (). Ci-dessous, un exemple très simple:

import com.jamonapi.*;
...
Monitor mon=MonitorFactory.start("myFirstMonitor");
...Code Being Timed...
mon.stop();

Découvrez cet article sur www.javaperformancetunning.com pour une belle présentation.

En utilisant AOP

Enfin, si vous ne voulez pas encombrer votre code avec ces mesures (ou si vous ne pouvez pas changer le code existant), alors AOP serait une arme parfaite. Je ne vais pas en discuter très profondément mais je voulais au moins le faire le mentionner.

Ci-dessous, un aspect très simple utilisant AspectJ et JAMon (ici, le nom court du pointcut sera utilisé pour le moniteur JAMon, d'où l'appel à thisJoinPoint.toShortString()):

public aspect MonitorAspect {
    pointcut monitor() : execution(* *.ClassToMonitor.methodToMonitor(..));

    Object arround() : monitor() {
        Monitor monitor = MonitorFactory.start(thisJoinPoint.toShortString());
        Object returnedObject = proceed();
        monitor.stop();
        return returnedObject;
    }
}

La définition de pointcut pourrait être facilement adaptée pour surveiller n'importe quelle méthode basée sur le nom de la classe, le nom du paquet, le nom de la méthode ou toute combinaison de ceux-ci. La mesure est vraiment un cas d'utilisation parfait pour AOP.

 195
Author: Pascal Thivent, 2013-10-24 11:50:24

Votre nouvelle classe:

public class TimeWatch {    
    long starts;

    public static TimeWatch start() {
        return new TimeWatch();
    }

    private TimeWatch() {
        reset();
    }

    public TimeWatch reset() {
        starts = System.currentTimeMillis();
        return this;
    }

    public long time() {
        long ends = System.currentTimeMillis();
        return ends - starts;
    }

    public long time(TimeUnit unit) {
        return unit.convert(time(), TimeUnit.MILLISECONDS);
    }
}

Utilisation:

    TimeWatch watch = TimeWatch.start();
    // do something
    long passedTimeInMs = watch.time();
    long passedTimeInSeconds = watch.time(TimeUnit.SECONDS);

Ensuite, le temps passé peut être converti dans le format que vous voulez, avec un calendrier par exemple

Greetz, GHad

 36
Author: GHad, 2014-12-05 09:39:24

Si le but est simplement d'imprimer des informations de synchronisation grossières dans vos journaux de programme, la solution facile pour les projets Java n'est pas d'écrire vos propres classes de chronomètre ou de minuterie, mais simplement d'utiliser le org.apache.commons.lang.time.StopWatch classe qui fait partie de Apache Commons Lang.

final StopWatch stopwatch = new StopWatch();
stopwatch.start();
LOGGER.debug("Starting long calculations: {}", stopwatch);
...
LOGGER.debug("Time after key part of calcuation: {}", stopwatch);
...
LOGGER.debug("Finished calculating {}", stopwatch);
 19
Author: David Bliss, 2016-02-11 18:08:42

Tl; dr

Par exemple si l'heure de début est 23:00 et l'heure de fin 1:00 pour obtenir une durée de 2:00.

Pas possible. Si vous n'avez que l'heure de la journée, l'horloge s'arrête à minuit. Sans le contexte des dates, comment savons-nous si vous voulez dire 1 AM le lendemain, la semaine prochaine, ou la prochaine décennie?

Donc, aller de 23 heures à 1 heure du MATIN signifie se déplaceren arrière dans le temps 22 heures, en exécutant les aiguilles de l'horloge dans le sens antihoraire. Voir le résultat ci-dessous, un négatif vingt-deux heures.

Duration.between(              // Represent a span of time a total number of seconds plus a fractional second in nanoseconds.
    LocalTime.of( 23 , 0 ) ,   // A time-of-day without a date and without a time zone. 
    LocalTime.of( 1 , 0 )      // A time-of-day clock stops at midnight. So getting to 1 AM from 11 PM means going backwards 22 hours.
)                              // Return a `Duration` object.
.toString()                    // Generate a `String` representing this span of time using standard ISO 8601 format: PnYnMnDTnHnMnS

PT-22H

Traverser minuit nécessite le contexte plus large de la date en plus de l'heure de la journée (voir ci-dessous).

Comment mesurer le temps écoulé en Java?

  1. Capturer le moment actuel dans l'UTC, avec Instant.now().
  2. Capturez un autre moment de ce type plus tard.
  3. Passer les deux à Duration.between.
  4. (a) À partir de l'objet Duration résultant, extraire un certain nombre de jours de 24 heures, heures, minutes, secondes et fraction de seconde en nanosecondes en appelant les différentes méthodes to…Part.
    (b) Ou, à l'appel de toString pour générer un String dans norme ISO 8601 de PnYnMnDTnHnMnS.

Exemple de code, en utilisant une paire de Instant objets.

Duration.between(    // Represent a span of time a total number of seconds plus a fractional second in nanoseconds.
    then ,           // Some other `Instant` object, captured earlier with `Instant.now()`.
    Instant.now()    // Capture the current moment in UTC with a resolution as fine as nanoseconds, depending on the limits of your host computer hardware clock and operating system. Generally you will get current moment in microseconds (six decimal digits of fractional second) in Java 9, 10, and 11, but only milliseconds in Java 8. 
)                    // Return a `Duration` object.
.toString()          // Generate a `String` representing this span of time using standard ISO 8601 format: PnYnMnDTnHnMnS

PT3M27. 602197S

Nouvelle Technologie Dans Java 8 +

Nous avons une nouvelle technologie pour cela maintenant intégré dans Java 8 et plus tard, le java.temps cadre.

Java.temps

Le java.le cadre temporel est défini par JSR 310, inspiré par le projet très réussi Joda-Time, étendu par le ThreeTen-Extraet décrit dans le Oracle Tutorial.

Les anciennes classes date-heure telles que java.util.Date/.Calendrier livré avec les premières versions de Java se sont avérés être mal conçu, déroutant et gênant. Ils sont supplantés par le java.temps classe.

Résolution

Autres réponses discuter de la résolution.

Le java.les classes de temps ont une résolution nanoseconde , jusqu'à neuf chiffres d'une fraction décimale de seconde. Par exemple, 2016-03-12T04:29:39.123456789Z.

Les deux vieux java.util.Date/.Les classes de calendrier et les classes Joda-Time ont une résolution en milliseconde (3 chiffres de fraction). Par exemple, 2016-03-12T04:29:39.123Z.

Dans Java 8, le moment actuel est récupéré avec une résolution allant jusqu'à la milliseconde à cause d'un problème hérité. Dans Java 9 et versions ultérieures, l'heure actuelle peut être déterminée jusqu'à une résolution de nanoseconde à condition que l'horloge matérielle de votre ordinateur fonctionne si finement.

Heure de la journée

Si vous voulez vraiment travailler avec seulement l'heure de la journée sans date ou fuseau horaire, utilisez le LocalTime classe.

LocalTime sooner = LocalTime.of ( 17, 00 );
LocalTime later = LocalTime.of ( 19, 00 );

Un Duration représente un laps de temps, en termes de nombre de secondes plus nanosecondes.

Duration duration = Duration.between ( sooner, later );

Vidage sur console.

System.out.println ( "sooner: " + sooner + " | later: " + later + " | duration: " + duration );

Plus tôt: 17:00 / plus tard: 19:00 / durée: PT2H

ISO 8601

Remarque la sortie par défaut de Duration::toString est au format standardISO 8601 . Dans ce format, le P marque le début (comme dans "Période"), et le T sépare toute partie années-mois-jours de la partie heures-minutes-secondes.

Passage à minuit

Malheureusement, travailler avec l'heure de la journée ne devient difficile que lorsque vous vous enroulez autour de l'horloge en traversant minuit. Le LocalTime la classe gère cela en supposant que vous voulez revenir à un point plus tôt dans la journée.

Utiliser le même code que ci-dessus mais passer de 23:00 à01:00 donne un résultat négatif de vingt-deux heures (PT-22H).

LocalTime sooner = LocalTime.of ( 23, 0 );
LocalTime later = LocalTime.of ( 1, 0 );

Plus tôt: 23:00 / plus tard: 01: 00 / durée: PT-22H

Date-Heure

Si vous avez l'intention de traverser minuit, il est probablement logique que vous travailliez avec des valeurs date-heure plutôt que des valeurs heure-jour uniquement.

Temps La Zone

Le fuseau horaire est crucial pour les dates. Nous spécifions donc trois éléments: (1) la date souhaitée, (2) l'heure souhaitée et (3) le fuseau horaire comme contexte pour interpréter cette date et cette heure. Ici, nous choisissons arbitrairement le fuseau horaire de la région de Montréal .

Si vous définissez la date de seulement un offset-de-UTC, utiliser un ZoneOffset avec un OffsetDateTime. Si vous avez un fuseau horaire complet (décalage plus règles de gestion des anomalies telles que la lumière du jour Gain de Temps), l'utilisation d'un ZoneId avec un ZonedDateTime.

LocalDate localDate = LocalDate.of ( 2016, 1, 23 );
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime sooner = ZonedDateTime.of ( localDate, LocalTime.of ( 23, 0 ), zoneId );

Nous spécifions l'heure la plus tardive comme le lendemain à 1h00 du matin.

ZonedDateTime later = ZonedDateTime.of ( localDate.plusDays ( 1 ), LocalTime.of ( 1, 0 ), zoneId );

Nous calculons le Duration de la même manière que vu ci-dessus. Maintenant, nous obtenons les deux heures attendues par cette question.

Duration duration = Duration.between ( sooner, later );

Vidage sur console.

System.out.println ( "sooner: " + sooner + " | later: " + later + " | duration: " + duration );

Plus tôt: 2016-01-23T23:00-05:00[Amérique/Montréal] | plus tard: 2016-01-24T01:00-05:00[Amérique/Montréal] | durée: PT2H

Heure d'été Temps

Si la date à portée de main avait impliqué l'heure d'été (DST) ou une autre anomalie de ce type, le java.les classes de temps s'ajusteraient au besoin. Lisez class doc pour plus de détails.


À propos de java.temps

Le java.temps framework est intégré à Java 8 et versions ultérieures. Ces classes permettent d'éviter la pénible vieux héritage date-heure classes telles que java.util.Date, Calendar, & SimpleDateFormat.

Le Joda-Temps le projet, maintenant en mode de maintenance, conseille la migration vers le java.temps classes.

Pour en savoir plus, voir le Tutoriel Oracle. Et rechercher Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310.

, Vous pouvez échanger java.temps objets directement avec votre base de données. Utilisez un pilote JDBC compatible avec JDBC 4.2 ou version ultérieure. Pas besoin de chaînes, pas besoin de classes java.sql.*.

Où obtenir le java.les classes de temps?

  • Java SE 8, Java SE 9, Java SE 10, et plus tard
    • Intégré.
    • Partie de l'API Java standard avec une implémentation groupée.
    • Java 9 ajoute quelques fonctionnalités et corrections mineures.
  • Java SE 6 et Java SE 7
    • Une grande partie du java.fonction temps est de retour, porté à Java 6 et 7ThreeTen-Backport.
  • Android
    • Versions ultérieures des implémentations Android bundle de java.les classes de temps.
    • Pour Android antérieur (Troisabp le projet adapte ThreeTen-Backport (mentionné ci-dessus). Voir Comment utiliser Troisabp....

Le Trois-Extra le projet étend java.temps avec des cours supplémentaires. Ce projet est un terrain d'essai pour d'éventuels ajouts futurs à java.temps. Vous pouvez trouver quelques classes utiles ici comme Interval, YearWeek, YearQuarter, et plus.

 14
Author: Basil Bourque, 2018-06-29 16:20:54

Java fournit la méthode statique System.currentTimeMillis(). Et cela renvoie une valeur longue, donc c'est une bonne référence. Beaucoup d'autres classes acceptent un paramètre 'timeInMillis' qui est aussi long.

Et beaucoup de gens trouvent plus facile d'utiliser la bibliothèque Joda Time pour faire des calculs sur les dates et les heures.

 7
Author: Andreas_D, 2015-05-27 06:22:32

Quels types utiliser pour accomplir cela en Java?

Réponse: longtemps

public class Stream {
    public long startTime;
    public long endTime;

    public long getDuration() {
        return endTime - startTime;
    }
    // I  would add
    public void start() {
        startTime = System.currentTimeMillis();
    }
    public void stop() {
         endTime = System.currentTimeMillis();
     }
}

Utilisation:

  Stream s = .... 

  s.start();

  // do something for a while 

  s.stop();

  s.getDuration(); // gives the elapsed time in milliseconds. 

C'est ma réponse directe à votre première question.

Pour la dernière "note", je vous suggère d'utiliser Joda Time. Il contient une classe interval adaptée à ce dont vous avez besoin.

 6
Author: OscarRyz, 2012-08-30 15:24:03

Il convient de noter que

  • Système.currentTimeMillis () n'a au mieux qu'une précision de la milliseconde. À la valeur de son peut être 16 ms sur certains systèmes Windows. Il a un coût inférieur à celui des alternatives
  • Système.nanoTime() n'est précis qu'à la micro-seconde sur la plupart des systèmes et peut sauter sur les systèmes Windows de 100 microsecondes (c'est-à-dire parfois pas aussi précis qu'il n'y paraît)
  • Le calendrier est un moyen très coûteux de calculer le temps. (je peux penser en dehors de XMLGregorianCalendar) Parfois, c'est la solution la plus appropriée, mais sachez que vous ne devez chronométrer que de longs intervalles.
 6
Author: Peter Lawrey, 2013-06-14 11:48:20

Si vous écrivez une application qui doit traiter des durées de temps, alors jetez un oeil à Joda-Time qui a une classe spécifiquement pour gérer les durées, Intervalles et Périodes. Votre méthode getDuration() semble pouvoir renvoyer un intervalle de temps Joda:

DateTime start = new DateTime(2004, 12, 25, 0, 0, 0, 0);
DateTime end = new DateTime(2005, 1, 1, 0, 0, 0, 0);

public Interval getInterval() {
    Interval interval = new Interval(start, end);
}
 3
Author: David Bliss, 2009-11-20 14:20:53

Si vous préférez utiliser l'API de calendrier de Java, vous pouvez essayer ceci,

Date startingTime = Calendar.getInstance().getTime();
//later on
Date now = Calendar.getInstance().getTime();
long timeElapsed = now.getTime() - startingTime.getTime();
 2
Author: James McMahon, 2009-11-20 13:04:08

Si vous obtenez vos horodatages à partir de System.currentTimeMillis(), vos variables de temps devraient être longues.

 1
Author: uckelman, 2009-11-20 11:52:43
Byte Stream Reader Elapsed Time for 23.7 MB is 96 secs

import java.io.*;
import java.io.IOException;
import java.util.Scanner;

class ElaspedTimetoCopyAFileUsingByteStream
{

    private long startTime = 0;
    private long stopTime = 0;
    private boolean running = false;


    public void start() 
    {
        this.startTime = System.currentTimeMillis();
        this.running = true;
    }


    public void stop() 
    {
        this.stopTime = System.currentTimeMillis();
        this.running = false;
    }



    public long getElapsedTime() 
    {
        long elapsed;
        if (running) {
             elapsed = (System.currentTimeMillis() - startTime);
        }
        else {
            elapsed = (stopTime - startTime);
        }
        return elapsed;
    }



    public long getElapsedTimeSecs()                 
    {
        long elapsed;
        if (running) 
        {
            elapsed = ((System.currentTimeMillis() - startTime) / 1000);
        }
        else
        {
            elapsed = ((stopTime - startTime) / 1000);
        }
        return elapsed;
    }





    public static void main(String[] args) throws IOException
    {
        ElaspedTimetoCopyAFileUsingByteStream  s = new ElaspedTimetoCopyAFileUsingByteStream();
        s.start();

        FileInputStream in = null;
        FileOutputStream out = null;

      try {
         in = new FileInputStream("vowels.txt");   // 23.7  MB File
         out = new FileOutputStream("output.txt");

         int c;
         while ((c = in.read()) != -1) {
            out.write(c);
         }
      }finally {
         if (in != null) {
            in.close();
         }
         if (out != null) {
            out.close();
         }
      }



        s.stop();
        System.out.println("elapsed time in seconds: " + s.getElapsedTimeSecs());
    }
}

[Elapsed Time for Byte Stream Reader][1]

**Character Stream Reader Elapsed Time for 23.7 MB is 3 secs**

import java.io.*;
import java.io.IOException;
import java.util.Scanner;

class ElaspedTimetoCopyAFileUsingCharacterStream
{

    private long startTime = 0;
    private long stopTime = 0;
    private boolean running = false;


    public void start() 
    {
        this.startTime = System.currentTimeMillis();
        this.running = true;
    }


    public void stop() 
    {
        this.stopTime = System.currentTimeMillis();
        this.running = false;
    }



    public long getElapsedTime() 
    {
        long elapsed;
        if (running) {
             elapsed = (System.currentTimeMillis() - startTime);
        }
        else {
            elapsed = (stopTime - startTime);
        }
        return elapsed;
    }



    public long getElapsedTimeSecs()                 
    {
        long elapsed;
        if (running) 
        {
            elapsed = ((System.currentTimeMillis() - startTime) / 1000);
        }
        else
        {
            elapsed = ((stopTime - startTime) / 1000);
        }
        return elapsed;
    }





    public static void main(String[] args) throws IOException
    {
        ElaspedTimetoCopyAFileUsingCharacterStream  s = new ElaspedTimetoCopyAFileUsingCharacterStream();
        s.start();

         FileReader in = null;                // CharacterStream Reader
      FileWriter out = null;

      try {
         in = new FileReader("vowels.txt");    // 23.7 MB
         out = new FileWriter("output.txt");

         int c;
         while ((c = in.read()) != -1) {
            out.write(c);
         }
      }finally {
         if (in != null) {
            in.close();
         }
         if (out != null) {
            out.close();
         }
      }

              s.stop();
        System.out.println("elapsed time in seconds: " + s.getElapsedTimeSecs());
    }
}


[Elapsed Time for Character Stream Reader][2]


  [1]: https://i.stack.imgur.com/hYo8y.png
  [2]: https://i.stack.imgur.com/xPjCK.png
 1
Author: Shiva Sagan, 2016-11-19 06:42:24

J'ai trouvé ce code utile pour chronométrer les choses:

public class Et {
    public Et() {
    reset();
    }
    public void reset() {
    t0=System.nanoTime();
    }
    public long t0() {
        return t0;
    }
    public long dt() {
        return System.nanoTime()-t0();
    }
    public double etms() {
    return etms(dt());
    }
    @Override public String toString() {
        return etms()+" ms.";
    }
    public static double etms(long dt) {
        return dt/1000000.; // 1_000_000. breaks cobertura
    }
    private Long t0;
}
 0
Author: Ray Tayek, 2016-03-16 23:17:53

Utilisez ceci:

SimpleDateFormat format = new SimpleDateFormat("HH:mm");

Date d1 = format.parse(strStartTime);
Date d2 = format.parse(strEndTime);

long diff = d2.getTime() - d1.getTime();
long diffSeconds,diffMinutes,diffHours;

if (diff > 0) {
diffSeconds = diff / 1000 % 60;
diffMinutes = diff / (60 * 1000) % 60;
diffHours = diff / (60 * 60 * 1000);
}
else{
long diffpos = (24*((60 * 60 * 1000))) + diff;
diffSeconds = diffpos / 1000 % 60;
diffMinutes = diffpos / (60 * 1000) % 60;
diffHours = (diffpos / (60 * 60 * 1000));
}

(Il est également important que, par exemple, si l'heure de début est 23:00 et l'heure de fin 1:00 pour obtenir une durée de 2:00.)

La partie "else" peut l'obtenir correctement

 0
Author: N. N, 2016-04-21 20:00:29

J'ai construit une fonction de formatage basée sur des choses que j'ai volées. J'avais besoin d'un moyen de "profiler" des choses dans les messages de journal, j'avais donc besoin d'un message de durée de longueur fixe.

public static String GetElapsed(long aInitialTime, long aEndTime, boolean aIncludeMillis)
{
  StringBuffer elapsed = new StringBuffer();

  Map<String, Long> units = new HashMap<String, Long>();

  long milliseconds = aEndTime - aInitialTime;

  long seconds = milliseconds / 1000;
  long minutes = milliseconds / (60 * 1000);
  long hours = milliseconds / (60 * 60 * 1000);
  long days = milliseconds / (24 * 60 * 60 * 1000);

  units.put("milliseconds", milliseconds);
  units.put("seconds", seconds);
  units.put("minutes", minutes);
  units.put("hours", hours);
  units.put("days", days);

  if (days > 0)
  {
    long leftoverHours = hours % 24;
    units.put("hours", leftoverHours);
  }

  if (hours > 0)
  {
    long leftoeverMinutes = minutes % 60;
    units.put("minutes", leftoeverMinutes);
  }

  if (minutes > 0)
  {
    long leftoverSeconds = seconds % 60;
    units.put("seconds", leftoverSeconds);
  }

  if (seconds > 0)
  {
    long leftoverMilliseconds = milliseconds % 1000;
    units.put("milliseconds", leftoverMilliseconds);
  }

  elapsed.append(PrependZeroIfNeeded(units.get("days")) + " days ")
      .append(PrependZeroIfNeeded(units.get("hours")) + " hours ")
      .append(PrependZeroIfNeeded(units.get("minutes")) + " minutes ")
      .append(PrependZeroIfNeeded(units.get("seconds")) + " seconds ")
      .append(PrependZeroIfNeeded(units.get("milliseconds")) + " ms");

  return elapsed.toString();

}

private static String PrependZeroIfNeeded(long aValue)
{
  return aValue < 10 ? "0" + aValue : Long.toString(aValue);
}

Et une classe de test:

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import junit.framework.TestCase;

public class TimeUtilsTest extends TestCase
{

  public void testGetElapsed()
  {
    long start = System.currentTimeMillis();
    GregorianCalendar calendar = (GregorianCalendar) Calendar.getInstance();
    calendar.setTime(new Date(start));

    calendar.add(Calendar.MILLISECOND, 610);
    calendar.add(Calendar.SECOND, 35);
    calendar.add(Calendar.MINUTE, 5);
    calendar.add(Calendar.DAY_OF_YEAR, 5);

    long end = calendar.getTimeInMillis();

    assertEquals("05 days 00 hours 05 minutes 35 seconds 610 ms", TimeUtils.GetElapsed(start, end, true));

  }

}
 0
Author: Buffalo, 2018-03-16 08:46:14