Comment convertir millisecondes en" X minutes, X secondes " en Java?

je veux enregistrer l'heure en utilisant System.currentTimeMillis() quand un utilisateur commence quelque chose dans mon programme. Quand il aura terminé, je soustrairai l'actuel System.currentTimeMillis() de la variable start , et je veux leur montrer le temps écoulé En utilisant un format lisible par l'homme tel que" XX heures, XX minutes, XX secondes "ou même" XX minutes, XX secondes " parce qu'il est peu probable de prendre quelqu'un une heure.

Quelle est la meilleure façon de faire cela?

503
demandé sur Click Upvote 2009-03-09 11:41:06

25 réponses

utiliser la 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))
);

Note: 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 de tête pour les valeurs 0-9, il suffit de faire:

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 la version 9 de L'API), 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...
1094
répondu siddhadev 2016-09-01 21:52:30

basé sur la réponse de @siddhadev, j'ai écrit une fonction qui convertit des millisecondes en 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());
    }
110
répondu Brent Writes Code 2018-02-10 22:00:41
long time = 1536259;

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

Imprime:

25:36:259

59
répondu Damien 2015-11-03 16:52:51

Uhm... combien de millisecondes sont dans un deuxième? Et en une minute? La Division n'est pas difficile.

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

Continue comme ça pendant des heures, des jours, des semaines, des mois, des années, des décennies, n'importe quoi.

34
répondu Bombe 2009-03-09 08:42:52

utilisant le java.time package en Java 8:

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

est au format de durée ISO 8601 : PT1M3.553S (1 minute et 3.553 secondes).

25
répondu Vitalii Fedorenko 2014-11-29 19:41:53

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

24
répondu Thilo 2013-05-06 10:16:50

deux divisions à la main, ou utiliser le SimpleDateFormat API .

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

Modifier par Bombe : il a été montré dans les commentaires que cette approche ne fonctionne que pour des durées plus courtes (c.-à-d. moins d'un jour).

23
répondu cadrian 2017-05-23 11:54:59

juste pour ajouter plus d'information 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 j'ai compris cela

19
répondu fredcrs 2011-05-25 16:52:49

je pense que la meilleure façon est:

String.format("%d min, %d sec", 
    TimeUnit.MILLISECONDS.toSeconds(length)/60,
    TimeUnit.MILLISECONDS.toSeconds(length) % 60 );
12
répondu Xtera 2011-04-06 10:01:52

solution la plus courte:

Voici probablement le plus court qui traite aussi des fuseaux horaires.

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

qui affiche par exemple:

00:18:32

explication:

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

%tT accepte aussi les longs comme entrée, donc pas besoin pour créer un Date . printf() affichera 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 pour que 0 millisecondes soit 0 heure et non la valeur de décalage horaire du fuseau horaire actuel.

Note #1: Si vous avez besoin du résultat comme un String , vous pouvez l'obtenir comme ceci:

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

Note #2: cela ne donne un résultat correct que si millis est inférieur à un jour parce que la partie de jour n'est pas incluse dans la sortie.

11
répondu icza 2016-02-27 16:38:13

Joda-Time

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
répondu dogbane 2014-08-06 18:54:22

pour Android sous API 9

(String.format("%d hr %d min, %d sec", millis/(1000*60*60), (millis%(1000*60*60))/(1000*60), ((millis%(1000*60*60))%(1000*60))/1000)) 
5
répondu Pradeep 2012-07-06 06:39:06

revisitant la contribution @brent-nash, nous pourrions utiliser la fonction de module au lieu des soustractions et utiliser la chaîne de caractères.méthode de format pour la chaîne de résultat:

  /**
   * 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 B Milliseconds".
   */
   public static String getDurationBreakdown(long millis) {
       if (millis < 0) {
          throw new IllegalArgumentException("Duration must be greater than zero!");
       }

       long days = TimeUnit.MILLISECONDS.toDays(millis);
       long hours = TimeUnit.MILLISECONDS.toHours(millis) % 24;
       long minutes = TimeUnit.MILLISECONDS.toMinutes(millis) % 60;
       long seconds = TimeUnit.MILLISECONDS.toSeconds(millis) % 60;
       long milliseconds = millis % 1000;

       return String.format("%d Days %d Hours %d Minutes %d Seconds %d Milliseconds",
                            days, hours, minutes, seconds, milliseconds);
   }
5
répondu Jose Tepedino 2018-02-09 13:17:44

pour les petits temps, moins d'une heure, je préfère:

long millis = ...

System.out.printf("%1$TM:%1$TS", millis);
// or
String str = String.format("%1$TM:%1$TS", millis);

pour les intervalles plus longs:

private static final long HOUR = TimeUnit.HOURS.toMillis(1);
...
if (millis < HOUR) {
    System.out.printf("%1$TM:%1$TS%n", millis);
} else {
    System.out.printf("%d:%2$TM:%2$TS%n", millis / HOUR, millis % HOUR);
}
3
répondu Carlos Heuberger 2011-04-05 15:49:34
    long startTime = System.currentTimeMillis();
    // do your work...
    long endTime=System.currentTimeMillis();
    long diff=endTime-startTime;       
    long hours=TimeUnit.MILLISECONDS.toHours(diff);
    diff=diff-(hours*60*60*1000);
    long min=TimeUnit.MILLISECONDS.toMinutes(diff);
    diff=diff-(min*60*1000);
    long seconds=TimeUnit.MILLISECONDS.toSeconds(diff);
    //hour, min and seconds variables contains the time elapsed on your work
3
répondu Fathah Rehman P 2013-07-23 19:26:53

Mon simple calcul:

String millisecToTime(int millisec) {
    int sec = millisec/1000;
    int second = sec % 60;
    int minute = sec / 60;
    if (minute >= 60) {
        int hour = minute / 60;
        minute %= 60;
        return hour + ":" + (minute < 10 ? "0" + minute : minute) + ":" + (second < 10 ? "0" + second : second);
    }
    return minute + ":" + (second < 10 ? "0" + second : second);
}

codage Heureux :)

3
répondu Shohan Ahmed Sijan 2017-01-26 20:26:57

Voici une réponse basée sur la réponse de Brent Nash, L'espoir qui aide !

public static String getDurationBreakdown(long millis)
{
    String[] units = {" Days ", " Hours ", " Minutes ", " Seconds "};
    Long[] values = new Long[units.length];
    if(millis < 0)
    {
        throw new IllegalArgumentException("Duration must be greater than zero!");
    }

    values[0] = TimeUnit.MILLISECONDS.toDays(millis);
    millis -= TimeUnit.DAYS.toMillis(values[0]);
    values[1] = TimeUnit.MILLISECONDS.toHours(millis);
    millis -= TimeUnit.HOURS.toMillis(values[1]);
    values[2] = TimeUnit.MILLISECONDS.toMinutes(millis);
    millis -= TimeUnit.MINUTES.toMillis(values[2]);
    values[3] = TimeUnit.MILLISECONDS.toSeconds(millis);

    StringBuilder sb = new StringBuilder(64);
    boolean startPrinting = false;
    for(int i = 0; i < units.length; i++){
        if( !startPrinting && values[i] != 0)
            startPrinting = true;
        if(startPrinting){
            sb.append(values[i]);
            sb.append(units[i]);
        }
    }

    return(sb.toString());
}
2
répondu Reda Bouaichi 2013-06-25 15:12:09

c'est plus facile en Java 9:

    Duration elapsedTime = Duration.ofMillis(millisDiff );
    String humanReadableElapsedTime = String.format(
            "%d hours, %d mins, %d seconds",
            elapsedTime.toHours(),
            elapsedTime.toMinutesPart(),
            elapsedTime.toSecondsPart());

cela produit une chaîne comme 0 hours, 39 mins, 9 seconds .

si vous voulez arrondir à la seconde entière avant le formatage:

    elapsedTime = elapsedTime.plusMillis(500).truncatedTo(ChronoUnit.SECONDS);

pour supprimer les heures si elles sont 0:

    long hours = elapsedTime.toHours();
    String humanReadableElapsedTime;
    if (hours == 0) {
        humanReadableElapsedTime = String.format(
                "%d mins, %d seconds",
                elapsedTime.toMinutesPart(),
                elapsedTime.toSecondsPart());

    } else {
        humanReadableElapsedTime = String.format(
                "%d hours, %d mins, %d seconds",
                hours,
                elapsedTime.toMinutesPart(),
                elapsedTime.toSecondsPart());
    }

Maintenant, nous pouvons avoir par exemple 39 mins, 9 seconds .

pour imprimer minutes et secondes avec zéro en tête pour les faire toujours deux chiffres, il suffit d'insérer 02 dans les spécificateurs de format appropriés, ainsi:

    String humanReadableElapsedTime = String.format(
            "%d hours, %02d mins, %02d seconds",
            elapsedTime.toHours(),
            elapsedTime.toMinutesPart(),
            elapsedTime.toSecondsPart());

Maintenant, nous pouvons avoir par exemple 0 hours, 39 mins, 09 seconds .

2
répondu Ole V.V. 2018-01-15 10:59:49

si vous savez que le décalage horaire est inférieur à une heure, vous pouvez utiliser le code suivant:

    Calendar c1 = Calendar.getInstance();
    Calendar c2 = Calendar.getInstance();

    c2.add(Calendar.MINUTE, 51);

    long diff = c2.getTimeInMillis() - c1.getTimeInMillis();

    c2.set(Calendar.MINUTE, 0);
    c2.set(Calendar.HOUR, 0);
    c2.set(Calendar.SECOND, 0);

    DateFormat df = new SimpleDateFormat("mm:ss");
    long diff1 = c2.getTimeInMillis() + diff;
    System.out.println(df.format(new Date(diff1)));

il en résulte à: 51: 00

1
répondu Gourav Singla 2014-09-22 11:41:02

cette réponse est similaire à certaines réponses ci-dessus. Cependant, je pense que ce serait bénéfique parce que, contrairement à d'autres réponses, cela supprimera toute virgule Ou espace supplémentaire et gère l'abréviation.

/**
 * Converts milliseconds to "x days, x hours, x mins, x secs"
 * 
 * @param millis
 *            The milliseconds
 * @param longFormat
 *            {@code true} to use "seconds" and "minutes" instead of "secs" and "mins"
 * @return A string representing how long in days/hours/minutes/seconds millis is.
 */
public static String millisToString(long millis, boolean longFormat) {
    if (millis < 1000) {
        return String.format("0 %s", longFormat ? "seconds" : "secs");
    }
    String[] units = {
            "day", "hour", longFormat ? "minute" : "min", longFormat ? "second" : "sec"
    };
    long[] times = new long[4];
    times[0] = TimeUnit.DAYS.convert(millis, TimeUnit.MILLISECONDS);
    millis -= TimeUnit.MILLISECONDS.convert(times[0], TimeUnit.DAYS);
    times[1] = TimeUnit.HOURS.convert(millis, TimeUnit.MILLISECONDS);
    millis -= TimeUnit.MILLISECONDS.convert(times[1], TimeUnit.HOURS);
    times[2] = TimeUnit.MINUTES.convert(millis, TimeUnit.MILLISECONDS);
    millis -= TimeUnit.MILLISECONDS.convert(times[2], TimeUnit.MINUTES);
    times[3] = TimeUnit.SECONDS.convert(millis, TimeUnit.MILLISECONDS);
    StringBuilder s = new StringBuilder();
    for (int i = 0; i < 4; i++) {
        if (times[i] > 0) {
            s.append(String.format("%d %s%s, ", times[i], units[i], times[i] == 1 ? "" : "s"));
        }
    }
    return s.toString().substring(0, s.length() - 2);
}

/**
 * Converts milliseconds to "x days, x hours, x mins, x secs"
 * 
 * @param millis
 *            The milliseconds
 * @return A string representing how long in days/hours/mins/secs millis is.
 */
public static String millisToString(long millis) {
    return millisToString(millis, false);
}
1
répondu Jared Rummler 2015-03-18 04:20:09

j'ai couvert cela dans une autre réponse mais vous pouvez faire:

public static Map<TimeUnit,Long> computeDiff(Date date1, Date date2) {
    long diffInMillies = date2.getTime() - date1.getTime();
    List<TimeUnit> units = new ArrayList<TimeUnit>(EnumSet.allOf(TimeUnit.class));
    Collections.reverse(units);
    Map<TimeUnit,Long> result = new LinkedHashMap<TimeUnit,Long>();
    long milliesRest = diffInMillies;
    for ( TimeUnit unit : units ) {
        long diff = unit.convert(milliesRest,TimeUnit.MILLISECONDS);
        long diffInMilliesForUnit = unit.toMillis(diff);
        milliesRest = milliesRest - diffInMilliesForUnit;
        result.put(unit,diff);
    }
    return result;
}

La sortie est quelque chose comme Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0} , avec les unités commandées.

C'est à vous de comprendre comment internationaliser ces données en fonction de la cible locale.

1
répondu Sebastien Lorber 2017-05-23 11:47:28

utilisez java.util.simultané.TimeUnit, et utilisez cette méthode simple:

private static long timeDiff(Date date, Date date2, TimeUnit unit) {
    long milliDiff=date2.getTime()-date.getTime();
    long unitDiff = unit.convert(milliDiff, TimeUnit.MILLISECONDS);
    return unitDiff; 
}

par exemple:

SimpleDateFormat sdf = new SimpleDateFormat("yy/MM/dd HH:mm:ss");  
Date firstDate = sdf.parse("06/24/2017 04:30:00");
Date secondDate = sdf.parse("07/24/2017 05:00:15");
Date thirdDate = sdf.parse("06/24/2017 06:00:15");

System.out.println("days difference: "+timeDiff(firstDate,secondDate,TimeUnit.DAYS));
System.out.println("hours difference: "+timeDiff(firstDate,thirdDate,TimeUnit.HOURS));
System.out.println("minutes difference: "+timeDiff(firstDate,thirdDate,TimeUnit.MINUTES));
System.out.println("seconds difference: "+timeDiff(firstDate,thirdDate,TimeUnit.SECONDS));
1
répondu Aramis Rodríguez Blanco 2018-06-04 08:59:04

il y a un problème. Quand millisecondes est 59999, en fait c'est 1 minute mais il sera calculé comme 59 secondes et 999 millisecondes est perdu.

Voici une version modifiée basée sur des réponses précédentes, qui peut résoudre cette perte:

public static String formatTime(long millis) {
    long seconds = Math.round((double) millis / 1000);
    long hours = TimeUnit.SECONDS.toHours(seconds);
    if (hours > 0)
        seconds -= TimeUnit.HOURS.toSeconds(hours);
    long minutes = seconds > 0 ? TimeUnit.SECONDS.toMinutes(seconds) : 0;
    if (minutes > 0)
        seconds -= TimeUnit.MINUTES.toSeconds(minutes);
    return hours > 0 ? String.format("%02d:%02d:%02d", hours, minutes, seconds) : String.format("%02d:%02d", minutes, seconds);
}
1
répondu Hexise 2018-09-23 14:06:18

pour cordes correctes ("1hour, 3sec", "3 min" mais pas "0 heure, 0 min, 3 sec") j'écris ce code:

int seconds = (int)(millis / 1000) % 60 ;
int minutes = (int)((millis / (1000*60)) % 60);
int hours = (int)((millis / (1000*60*60)) % 24);
int days = (int)((millis / (1000*60*60*24)) % 365);
int years = (int)(millis / 1000*60*60*24*365);

ArrayList<String> timeArray = new ArrayList<String>();

if(years > 0)   
    timeArray.add(String.valueOf(years)   + "y");

if(days > 0)    
    timeArray.add(String.valueOf(days) + "d");

if(hours>0)   
    timeArray.add(String.valueOf(hours) + "h");

if(minutes>0) 
    timeArray.add(String.valueOf(minutes) + "min");

if(seconds>0) 
    timeArray.add(String.valueOf(seconds) + "sec");

String time = "";
for (int i = 0; i < timeArray.size(); i++) 
{
    time = time + timeArray.get(i);
    if (i != timeArray.size() - 1)
        time = time + ", ";
}

if (time == "")
  time = "0 sec";
0
répondu John 2012-02-08 16:06:35

j'ai modifié la réponse de @MyKuLLSKI et ajouté le support de plurlization. J'ai pris des secondes parce que je n'en avais pas besoin, mais n'hésitez pas à les rajouter si vous en avez besoin.

public static String intervalToHumanReadableTime(int intervalMins) {

    if(intervalMins <= 0) {
        return "0";
    } else {

        long intervalMs = intervalMins * 60 * 1000;

        long days = TimeUnit.MILLISECONDS.toDays(intervalMs);
        intervalMs -= TimeUnit.DAYS.toMillis(days);
        long hours = TimeUnit.MILLISECONDS.toHours(intervalMs);
        intervalMs -= TimeUnit.HOURS.toMillis(hours);
        long minutes = TimeUnit.MILLISECONDS.toMinutes(intervalMs);

        StringBuilder sb = new StringBuilder(12);

        if (days >= 1) {
            sb.append(days).append(" day").append(pluralize(days)).append(", ");
        }

        if (hours >= 1) {
            sb.append(hours).append(" hour").append(pluralize(hours)).append(", ");
        }

        if (minutes >= 1) {
            sb.append(minutes).append(" minute").append(pluralize(minutes));
        } else {
            sb.delete(sb.length()-2, sb.length()-1);
        }

        return(sb.toString());          

    }

}

public static String pluralize(long val) {
    return (Math.round(val) > 1 ? "s" : "");
}
0
répondu bitstream 2015-07-13 18:47:51