Question Comment convertir Millisecondes en "X minutes, x secondes" en Java?


Je veux enregistrer le temps en utilisant System.currentTimeMillis() quand un utilisateur commence quelque chose dans mon programme. Quand il finira, je soustrais le courant System.currentTimeMillis() du start variable, et je veux leur montrer le temps écoulé en utilisant un format lisible pour l'homme, tel que "XX heures, XX minutes, XX secondes" ou même "XX minutes, XX secondes" car il est peu probable que quelqu'un prenne une heure.

Quelle est la meilleure façon de faire cela?


491
2018-03-09 08:41


origine


Réponses:


Utilisez le java.util.concurrent.TimeUnit classe:

String.format("%d min, %d sec", 
    TimeUnit.MILLISECONDS.toMinutes(millis),
    TimeUnit.MILLISECONDS.toSeconds(millis) - 
    TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))
);

Remarque: TimeUnit fait partie de la spécification Java 1.5, mais toMinutes a été ajouté à partir de Java 1.6.

Pour ajouter un zéro non significatif pour les valeurs 0-9, procédez comme suit:

String.format("%02d min, %02d sec", 
    TimeUnit.MILLISECONDS.toMinutes(millis),
    TimeUnit.MILLISECONDS.toSeconds(millis) - 
    TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))
);

Si TimeUnit ou toMinutes ne sont pas pris en charge (comme sur Android avant API version 9), utilisez les équations suivantes:

int seconds = (int) (milliseconds / 1000) % 60 ;
int minutes = (int) ((milliseconds / (1000*60)) % 60);
int hours   = (int) ((milliseconds / (1000*60*60)) % 24);
//etc...

1074
2018-03-09 10:01



Basé sur la réponse de @ siddhadev, j'ai écrit une fonction qui convertit des millisecondes en une chaîne formatée:

   /**
     * Convert a millisecond duration to a string format
     * 
     * @param millis A duration to convert to a string form
     * @return A string of the form "X Days Y Hours Z Minutes A Seconds".
     */
    public static String getDurationBreakdown(long millis) {
        if(millis < 0) {
            throw new IllegalArgumentException("Duration must be greater than zero!");
        }

        long days = TimeUnit.MILLISECONDS.toDays(millis);
        millis -= TimeUnit.DAYS.toMillis(days);
        long hours = TimeUnit.MILLISECONDS.toHours(millis);
        millis -= TimeUnit.HOURS.toMillis(hours);
        long minutes = TimeUnit.MILLISECONDS.toMinutes(millis);
        millis -= TimeUnit.MINUTES.toMillis(minutes);
        long seconds = TimeUnit.MILLISECONDS.toSeconds(millis);

        StringBuilder sb = new StringBuilder(64);
        sb.append(days);
        sb.append(" Days ");
        sb.append(hours);
        sb.append(" Hours ");
        sb.append(minutes);
        sb.append(" Minutes ");
        sb.append(seconds);
        sb.append(" Seconds");

        return(sb.toString());
    }

104
2017-10-05 15:41



long time = 1536259;

return (new SimpleDateFormat("mm:ss:SSS")).format(new Date(time));

Impressions:

25: 36: 259


54
2018-02-16 12:14



Uhm ... combien de millisecondes y a-t-il en une seconde? Et dans une minute? La division n'est pas si difficile.

int seconds = (int) ((milliseconds / 1000) % 60);
int minutes = (int) ((milliseconds / 1000) / 60);

Continuez comme ça pendant des heures, des jours, des semaines, des mois, des années, des décennies, peu importe.


33
2018-03-09 08:42



Je ne tirerais pas la dépendance supplémentaire juste pour cela (la division n'est pas si difficile, après tout), mais si vous utilisez de toute façon Commons Lang, il y a les DuréeFormatUtils.


24
2018-03-09 08:48



En utilisant le package java.time en Java 8:

Instant start = Instant.now();
Thread.sleep(63553);
Instant end = Instant.now();
System.out.println(Duration.between(start, end));

La sortie est en ISO 8601 Format de durée: PT1M3.553S (1 minute et 3,553 secondes).


24
2018-04-19 23:09



Soit les divisions de la main, ou utiliser le API SimpleDateFormat.

long start = System.currentTimeMillis();
// do your work...
long elapsed = System.currentTimeMillis() - start;
DateFormat df = new SimpleDateFormat("HH 'hours', mm 'mins,' ss 'seconds'");
df.setTimeZone(TimeZone.getTimeZone("GMT+0"));
System.out.println(df.format(new Date(elapsed)));

Édité par Bombe: Il a été montré dans les commentaires que cette approche ne fonctionne que pour des durées plus courtes (c'est-à-dire moins d'une journée).


23
2018-03-09 08:45



Juste pour ajouter plus d'info si vous voulez formater comme: HH: mm: ss

0 <= HH <= infini

0 <= mm <60

0 <= ss <60

utilisez ceci:

int h = (int) ((startTimeInMillis / 1000) / 3600);
int m = (int) (((startTimeInMillis / 1000) / 60) % 60);
int s = (int) ((startTimeInMillis / 1000) % 60);

Je viens d'avoir ce problème maintenant et compris cela


19
2018-05-25 16:52



Je pense que le meilleur moyen est de:

String.format("%d min, %d sec", 
    TimeUnit.MILLISECONDS.toSeconds(length)/60,
    TimeUnit.MILLISECONDS.toSeconds(length) % 60 );

12
2018-04-05 15:04



La solution la plus courte

Voici probablement le plus court qui concerne également les fuseaux horaires.

System.out.printf("%tT", millis-TimeZone.getDefault().getRawOffset());

Quelles sorties par exemple:

00:18:32

Explication:

%tT est l'heure formatée pour l'horloge de 24 heures %tH:%tM:%tS.

%tT accepte également les longs comme entrée, donc pas besoin de créer un Date. printf() imprimera simplement l'heure spécifiée en millisecondes, mais dans le fuseau horaire actuel, nous devons donc soustraire le décalage brut du fuseau horaire actuel de sorte que 0 milliseconde soit 0 heure et non la valeur de décalage temporel du fuseau horaire actuel.

Note 1: Si vous avez besoin du résultat en tant que String, vous pouvez l'obtenir comme ceci:

String t = String.format("%tT", millis-TimeZone.getDefault().getRawOffset());

Note 2: Cela donne seulement un résultat correct si millis est inférieur à un jour car la partie jour n'est pas incluse dans la sortie.


11
2017-07-17 09:34



Joda-Time

En utilisant Joda-Time:

DateTime startTime = new DateTime();

// do something

DateTime endTime = new DateTime();
Duration duration = new Duration(startTime, endTime);
Period period = duration.toPeriod().normalizedStandard(PeriodType.time());
System.out.println(PeriodFormat.getDefault().print(period));

6
2017-11-13 14:24