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

118

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.

FlySwat
la source
"Le langage que j'utilise n'a pas cela intégré, sinon je l'utiliserais." J'ai du mal à comprendre. Quelle langue? Quel OS?
S.Lott
ActionScript, n'importe quel système d'exploitation, il a un support de date / heure misérable
FlySwat
3
Je ne connais aucun langage qui ait ce qu'il demande, et je ne vois aucune raison pour laquelle ce serait le cas. Quelques calculs très simples de division / module obtiennent la réponse très bien.
Kip
1
Toutes les années n'ont pas le même nombre de jours, il faudrait donc indiquer de quelle période il s'agit. Ou peut-être que vous le voulez juste dans les années «standard» (365 quelque chose)?
Milan Babuškov
@Kip: OK - j'ai mal lu la question - pensait aux horodatages du système d'exploitation en millisecondes. Pas de temps ou d'intervalles delta. Tenté de modifier la question ...
S.Lott

Réponses:

226

Eh bien, puisque personne d'autre n'a intensifié, je vais écrire le code facile pour le faire:

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é à des jours et que vous n'ayez pas demandé pendant des mois. :)

Notez que dans ce qui précède, on suppose que cela /représente une division entière tronquée. Si vous utilisez ce code dans un langage où /représente la division en virgule flottante, vous devrez tronquer manuellement les résultats de la division si nécessaire.

Greg Hewgill
la source
2
Je viens de l'utiliser dans une fonction flash. Merci! (voté pour plus de simplicité)
Makram Saleh
2
Cela ne fonctionne pas correctement. Devrait utiliser parseInt lors de l'utilisation du diviseur, sinon vous verrez des valeurs flottantes longues. Voir ma réponse ci-dessous pour une solution plus complète.
Rajiv
17
@Greg Hewgill Je suis juste content que vous vous soyez arrêté quelques jours et que vous n'ayez pas demandé pendant des mois. :) haha :)
moshfiqur
58

Soit A le nombre de millisecondes. Ensuite, vous avez:

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

et ainsi de suite ( %est l'opérateur de module).

J'espère que cela t'aides.

Gabriele D'Antona
la source
@sabbibJAVA 24 aurait dû fonctionner. Dans quelle langue êtes-vous? Si /fait la division en virgule flottante, vous devez tronquer la valeur. Il est supposé dans d'autres réponses qui /effectue une division entière.
Brian J
24

Les deux solutions ci-dessous utilisent javascript (je ne savais pas que la solution était indépendante du langage!). Les deux solutions devront être étendues si les durées de capture> 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 lorsque 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 les champs dont vous avez besoin. Le formatage d'un horodatage devient alors simple ...

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

Donne:

"6 days, 5 hours, 4 minutes, 3 seconds, 21 millis"
Nick Grealy
la source
Changez cette ligne pour obtenir le singulier et le pluriel return dur[u.label] + " " + (dur[u.label]==1?u.label.slice(0,-1):u.label);
Phillip Kamikaze
1
@PhillipKamikaze Merci Phillip! J'ai incorporé votre suggestion.
Nick Grealy
Vous ne voulez probablement pas afficher les segments avec des valeurs nulles, donc le filtre suivant pourrait être ajouté ... var nonZero = function(u){ return !u.startsWith("0"); }; // convert object to a string representation... dur.toString = function(){ return units.reverse().map(function(u){ return dur[u.label] + " " + (dur[u.label]==1?u.label.slice(0,-1):u.label); }).filter(nonZero).join(', '); };
Ruslan Ulanov
1
Merci @RuslanUlanov! Je l'ai ajouté à l'exemple (mais avec une légère modification pour vérifier si le nombre est "véridique").
Nick Grealy
7

Vous devriez utiliser les fonctions datetime de la langue que vous utilisez, mais, juste pour vous amuser, 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;
Albertein
la source
4

C'est une méthode que j'ai écrite. Il prend un integer milliseconds valueet 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;

}
iTurki
la source
4
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();
}
Rajiv
la source
2

Je suggérerais d'utiliser les fonctions / bibliothèques de date / heure fournies par votre langue / cadre de choix. Consultez également les fonctions de formatage de chaîne, car elles fournissent souvent des moyens simples de transmettre des dates / horodatages et de générer un format de chaîne lisible par l'homme.

ourson
la source
2

Vos choix sont simples:

  1. Écrivez le code pour effectuer la conversion (c.-à-d. 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 1000 pour les 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.
socle
la source
2
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
);
Krolique
la source
2
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

Tel quel
la source
2

Pourquoi ne pas faire 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.0010000000000000002

Et traitant de la précision flottante, par exemple Number (minutes.toFixed (5)) //1.44

Pavel Blagodov
la source
2

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
Camilo Silva
la source
1

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 à 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 
Rafal Pastuszak
la source
1

Ceci 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);
ssamuel68
la source
1

Voici ma solution en utilisant TimeUnit.

MISE À JOUR: 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"
dafunker
la source
1

Une façon 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 régler l' heure comme paramètre si vous souhaitez contrôler les plages horaires.

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(" : ")    );
Yorg
la source
1

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

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

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

il s’imprimera comme «à 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"

DroidDev
la source
0

Voici une méthode plus précise en 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);
        }
    }
AK Joshi
la source