web-dev-qa-db-fra.com

Comment convertir des millisecondes en une forme lisible par l'homme?

J'ai besoin de convertir une quantité arbitraire de millisecondes en jours, heures, minutes, secondes.

Par exemple: 10 jours, 5 heures, 13 minutes, 1 seconde.

117
FlySwat

Eh bien, puisque personne d'autre n'a pris la relève, j'écrirai le code facile à suivre:

x = ms / 1000
seconds = x % 60
x /= 60
minutes = x % 60
x /= 60
hours = x % 24
x /= 24
days = x

Je suis juste content que vous vous soyez arrêté pendant des jours et que vous n'ayez pas demandé pendant des mois. :)

Notez que dans ce qui précède, on suppose que / représente une division entière tronquée. Si vous utilisez ce code dans une langue où / représente une division en virgule flottante, vous devrez tronquer manuellement les résultats de la division selon vos besoins.

222
Greg Hewgill

Soit A la quantité de millisecondes. Ensuite vous avez:

seconds=(A/1000)%60
minutes=(A/(1000*60))%60
hours=(A/(1000*60*60))%24

etc (% est l'opérateur de module).

J'espère que cela t'aides.

56

Les deux solutions ci-dessous utilisent javascript (je ne savais pas que la solution était agnostique!). Les deux solutions devront être étendues si les durées sont capturées > 1 month.

Solution 1: utilisez l'objet Date

var date = new Date(536643021);
var str = '';
str += date.getUTCDate()-1 + " days, ";
str += date.getUTCHours() + " hours, ";
str += date.getUTCMinutes() + " minutes, ";
str += date.getUTCSeconds() + " seconds, ";
str += date.getUTCMilliseconds() + " millis";
console.log(str);

Donne:

"6 days, 5 hours, 4 minutes, 3 seconds, 21 millis"

Les bibliothèques sont utiles, mais pourquoi utiliser une bibliothèque quand vous pouvez réinventer la roue! :)

Solution 2: écrivez votre propre analyseur

var getDuration = function(millis){
    var dur = {};
    var units = [
        {label:"millis",    mod:1000},
        {label:"seconds",   mod:60},
        {label:"minutes",   mod:60},
        {label:"hours",     mod:24},
        {label:"days",      mod:31}
    ];
    // calculate the individual unit values...
    units.forEach(function(u){
        millis = (millis - (dur[u.label] = (millis % u.mod))) / u.mod;
    });
    // convert object to a string representation...
    var nonZero = function(u){ return dur[u.label]; };
    dur.toString = function(){
        return units
            .reverse()
            .filter(nonZero)
            .map(function(u){
                return dur[u.label] + " " + (dur[u.label]==1?u.label.slice(0,-1):u.label);
            })
            .join(', ');
    };
    return dur;
};

Crée un objet "durée", avec tous les champs nécessaires. Formater un horodatage devient alors simple ...

console.log(getDuration(536643021).toString());

Donne:

"6 days, 5 hours, 4 minutes, 3 seconds, 21 millis"
24
Nick Grealy

Apache Commons Lang a un DurationFormatUtils qui a des méthodes très utiles comme formatDurationWords .

20
David Dossot

Vous devriez utiliser les fonctions datetime de la langue que vous utilisez, mais, pour le plaisir, voici le code:

int milliseconds = someNumber;

int seconds = milliseconds / 1000;

int minutes = seconds / 60;

seconds %= 60;

int hours = minutes / 60;

minutes %= 60;

int days = hours / 24;

hours %= 24;
7
albertein

Ceci est une méthode que j'ai écrite. Il faut un integer milliseconds value et retourne un human-readable String:

public String convertMS(int ms) {
    int seconds = (int) ((ms / 1000) % 60);
    int minutes = (int) (((ms / 1000) / 60) % 60);
    int hours = (int) ((((ms / 1000) / 60) / 60) % 24);

    String sec, min, hrs;
    if(seconds<10)  sec="0"+seconds;
    else            sec= ""+seconds;
    if(minutes<10)  min="0"+minutes;
    else            min= ""+minutes;
    if(hours<10)    hrs="0"+hours;
    else            hrs= ""+hours;

    if(hours == 0)  return min+":"+sec;
    else    return hrs+":"+min+":"+sec;

}
4
iTurki
function convertTime(time) {        
    var millis= time % 1000;
    time = parseInt(time/1000);
    var seconds = time % 60;
    time = parseInt(time/60);
    var minutes = time % 60;
    time = parseInt(time/60);
    var hours = time % 24;
    var out = "";
    if(hours && hours > 0) out += hours + " " + ((hours == 1)?"hr":"hrs") + " ";
    if(minutes && minutes > 0) out += minutes + " " + ((minutes == 1)?"min":"mins") + " ";
    if(seconds && seconds > 0) out += seconds + " " + ((seconds == 1)?"sec":"secs") + " ";
    if(millis&& millis> 0) out += millis+ " " + ((millis== 1)?"msec":"msecs") + " ";
    return out.trim();
}
4
Rajiv

En java

public static String formatMs(long millis) {
    long hours = TimeUnit.MILLISECONDS.toHours(millis);
    long mins = TimeUnit.MILLISECONDS.toMinutes(millis);
    long secs = TimeUnit.MILLISECONDS.toSeconds(millis);
    return String.format("%dh %d min, %d sec",
            hours,
            mins - TimeUnit.HOURS.toMinutes(hours),
            secs - TimeUnit.MINUTES.toSeconds(mins)
    );
}

Donne quelque chose comme ça:

12h 1 min, 34 sec
2
Camilo Silva

Je suggérerais d'utiliser les fonctions/bibliothèques de date/heure que votre langage/structure de choix fournit. Découvrez également les fonctions de formatage de chaîne, car elles offrent souvent des moyens simples de passer la date/l'horodatage et de générer un format de chaîne lisible par l'homme.

2
theraccoonbear
Long expireTime = 69l;
Long tempParam = 0l;

Long seconds = math.mod(expireTime, 60);
tempParam = expireTime - seconds;
expireTime = tempParam/60;
Long minutes = math.mod(expireTime, 60);
tempParam = expireTime - minutes;
expireTime = expireTime/60;
Long hours = math.mod(expireTime, 24);
tempParam = expireTime - hours;
expireTime = expireTime/24;
Long days = math.mod(expireTime, 30);

system.debug(days + '.' + hours + ':' + minutes + ':' + seconds);

Cela devrait imprimer: 0.0: 1: 9

2
Asit

Vos choix sont simples:

  1. Écrivez le code pour effectuer la conversion (divisez par milliSecondsPerDay pour obtenir des jours et utilisez le module pour diviser par milliSecondsPerHour pour obtenir des heures et utilisez le module pour diviser par milliSecondsPerMinute et divisez par 1 000 pendant des secondes. MilliSecondsPerMinute = 60000, milliSecondsPerHour = 60 milliSecondsPerMinute, milliSecondsPerDay = 24 * milliSecondsPerHour.
  2. Utilisez une routine d'exploitation quelconque. UNIX et Windows ont tous deux des structures que vous pouvez obtenir à partir d'une valeur de type Ticks ou seconds.
2
plinth
Long serverUptimeSeconds = 
    (System.currentTimeMillis() - SINCE_TIME_IN_MILLISECONDS) / 1000;


String serverUptimeText = 
String.format("%d days %d hours %d minutes %d seconds",
serverUptimeSeconds / 86400,
( serverUptimeSeconds % 86400) / 3600 ,
((serverUptimeSeconds % 86400) % 3600 ) / 60,
((serverUptimeSeconds % 86400) % 3600 ) % 60
);
2
Krolique

Pourquoi ne faites-vous pas quelque chose comme ça:

var ms = 86400;

var secondes = ms/1000; //86.4

var minutes = secondes/60; //1.4400000000000002

var heures = minutes/60; //0.024000000000000004

var jours = heures/24; //0.00100000000000000000002

Et traiter avec la précision de flottement, par exemple. Nombre (minutes.toFixed (5)) //1.44

2
Pavel Blagodov

Je suggère d'utiliser http://www.ocpsoft.org/prettytime/ bibliothèque ..

il est très simple d'obtenir un intervalle de temps sous forme lisible par l'homme comme

PrettyTime p = new PrettyTime(); System.out.println(p.format(new Date()));

il va imprimer comme "moments à partir de maintenant"

autre exemple

PrettyTime p = new PrettyTime()); Date d = new Date(System.currentTimeMillis()); d.setHours(d.getHours() - 1); String ago = p.format(d);

then string ago = "il y a 1 heure"

1
DroidDev

Une manière flexible de le faire:
(Pas fait pour la date actuelle mais assez bon pour les durées)

/**
convert duration to a ms/sec/min/hour/day/week array
@param {int}        msTime              : time in milliseconds 
@param {bool}       fillEmpty(optional) : fill array values even when they are 0.
@param {string[]}   suffixes(optional)  : add suffixes to returned values.
                                        values are filled with missings '0'
@return {int[]/string[]} : time values from higher to lower(ms) range.
*/
var msToTimeList=function(msTime,fillEmpty,suffixes){
    suffixes=(suffixes instanceof Array)?suffixes:[];   //suffixes is optional
    var timeSteps=[1000,60,60,24,7];    // time ranges : ms/sec/min/hour/day/week
    timeSteps.Push(1000000);    //add very big time at the end to stop cutting
    var result=[];
    for(var i=0;(msTime>0||i<1||fillEmpty)&&i<timeSteps.length;i++){
        var timerange = msTime%timeSteps[i];
        if(typeof(suffixes[i])=="string"){
            timerange+=suffixes[i]; // add suffix (converting )
            // and fill zeros :
            while(  i<timeSteps.length-1 &&
                    timerange.length<((timeSteps[i]-1)+suffixes[i]).length  )
                timerange="0"+timerange;
        }
        result.unshift(timerange);  // stack time range from higher to lower
        msTime = Math.floor(msTime/timeSteps[i]);
    }
    return result;
};

NB: vous pouvez également définir timeSteps en tant que paramètre si vous souhaitez contrôler les plages de temps.

comment utiliser (copier un test):

var elsapsed = Math.floor(Math.random()*3000000000);

console.log(    "elsapsed (labels) = "+
        msToTimeList(elsapsed,false,["ms","sec","min","h","days","weeks"]).join("/")    );

console.log(    "half hour : "+msToTimeList(elsapsed,true)[3]<30?"first":"second"   );

console.log(    "elsapsed (classic) = "+
        msToTimeList(elsapsed,false,["","","","","",""]).join(" : ")    );
1
yorg

C'est une solution. Plus tard, vous pouvez diviser par ":" et prendre les valeurs du tableau

/**
 * Converts milliseconds to human readeable language separated by ":"
 * Example: 190980000 --> 2:05:3 --> 2days 5hours 3min
 */
function dhm(t){
    var cd = 24 * 60 * 60 * 1000,
        ch = 60 * 60 * 1000,
        d = Math.floor(t / cd),
        h = '0' + Math.floor( (t - d * cd) / ch),
        m = '0' + Math.round( (t - d * cd - h * ch) / 60000);
    return [d, h.substr(-2), m.substr(-2)].join(':');
}

var delay = 190980000;                   
var fullTime = dhm(delay);
console.log(fullTime);
1
ssamuel68

Voici ma solution en utilisant TimeUnit.

UPDATE: Je dois souligner que cela est écrit en groovy, mais Java est presque identique.

def remainingStr = ""

/* Days */
int days = MILLISECONDS.toDays(remainingTime) as int
remainingStr += (days == 1) ? '1 Day : ' : "${days} Days : "
remainingTime -= DAYS.toMillis(days)

/* Hours */
int hours = MILLISECONDS.toHours(remainingTime) as int
remainingStr += (hours == 1) ? '1 Hour : ' : "${hours} Hours : "
remainingTime -= HOURS.toMillis(hours)

/* Minutes */
int minutes = MILLISECONDS.toMinutes(remainingTime) as int
remainingStr += (minutes == 1) ? '1 Minute : ' : "${minutes} Minutes : "
remainingTime -= MINUTES.toMillis(minutes)

/* Seconds */
int seconds = MILLISECONDS.toSeconds(remainingTime) as int
remainingStr += (seconds == 1) ? '1 Second' : "${seconds} Seconds"
1
dafunker

Je ne peux pas commenter la première réponse à votre question, mais il y a une petite erreur. Vous devez utiliser parseInt ou Math.floor pour convertir les nombres en virgule flottante en entier, i

var days, hours, minutes, seconds, x;
x = ms / 1000;
seconds = Math.floor(x % 60);
x /= 60;
minutes = Math.floor(x % 60);
x /= 60;
hours = Math.floor(x % 24);
x /= 24;
days = Math.floor(x);

Personnellement, j'utilise CoffeeScript dans mes projets et mon code ressemble à ça:

getFormattedTime : (ms)->
        x = ms / 1000
        seconds = Math.floor x % 60
        x /= 60
        minutes = Math.floor x % 60
        x /= 60
        hours = Math.floor x % 24
        x /= 24
        days = Math.floor x
        formattedTime = "#{seconds}s"
        if minutes then formattedTime = "#{minutes}m " + formattedTime
        if hours then formattedTime = "#{hours}h " + formattedTime
        formattedTime 
1
Rafal Pastuszak

Voici une méthode plus précise dans Java, j'ai implémenté cette logique simple, j'espère que cela vous aidera:

    public String getDuration(String _currentTimemilliSecond)
    {
        long _currentTimeMiles = 1;         
        int x = 0;
        int seconds = 0;
        int minutes = 0;
        int hours = 0;
        int days = 0;
        int month = 0;
        int year = 0;

        try 
        {
            _currentTimeMiles = Long.parseLong(_currentTimemilliSecond);
            /**  x in seconds **/   
            x = (int) (_currentTimeMiles / 1000) ; 
            seconds = x ;

            if(seconds >59)
            {
                minutes = seconds/60 ;

                if(minutes > 59)
                {
                    hours = minutes/60;

                    if(hours > 23)
                    {
                        days = hours/24 ;

                        if(days > 30)
                        {
                            month = days/30;

                            if(month > 11)
                            {
                                year = month/12;

                                Log.d("Year", year);
                                Log.d("Month", month%12);
                                Log.d("Days", days % 30);
                                Log.d("hours ", hours % 24);
                                Log.d("Minutes ", minutes % 60);
                                Log.d("Seconds  ", seconds % 60);   

                                return "Year "+year + " Month "+month%12 +" Days " +days%30 +" hours "+hours%24 +" Minutes "+minutes %60+" Seconds "+seconds%60;
                            }
                            else
                            {
                                Log.d("Month", month);
                                Log.d("Days", days % 30);
                                Log.d("hours ", hours % 24);
                                Log.d("Minutes ", minutes % 60);
                                Log.d("Seconds  ", seconds % 60);   

                                return "Month "+month +" Days " +days%30 +" hours "+hours%24 +" Minutes "+minutes %60+" Seconds "+seconds%60;
                            }

                        }
                        else
                        {
                            Log.d("Days", days );
                            Log.d("hours ", hours % 24);
                            Log.d("Minutes ", minutes % 60);
                            Log.d("Seconds  ", seconds % 60);   

                            return "Days " +days +" hours "+hours%24 +" Minutes "+minutes %60+" Seconds "+seconds%60;
                        }

                    }
                    else
                    {
                        Log.d("hours ", hours);
                        Log.d("Minutes ", minutes % 60);
                        Log.d("Seconds  ", seconds % 60);

                        return "hours "+hours+" Minutes "+minutes %60+" Seconds "+seconds%60;
                    }
                }
                else
                {
                    Log.d("Minutes ", minutes);
                    Log.d("Seconds  ", seconds % 60);

                    return "Minutes "+minutes +" Seconds "+seconds%60;
                }
            }
            else
            {
                Log.d("Seconds ", x);
                return " Seconds "+seconds;
            }
        }
        catch (Exception e) 
        {
            Log.e(getClass().getName().toString(), e.toString());
        }
        return "";
    }

    private Class Log
    {
        public static void d(String tag , int value)
        {
            System.out.println("##### [ Debug ]  ## "+tag +" :: "+value);
        }
    }
0
AK Joshi