79 votes

Convertissez l'intervalle de temps donné en secondes en une forme plus lisible pour l'homme.

J'ai besoin d'un extrait de code pour convertir la quantité de temps donnée par le nombre de secondes en une forme lisible par l'homme. La fonction doit recevoir un nombre et produire une chaîne de caractères comme ceci :

34 seconds 
12 minutes 
4 hours 
5 days 
4 months
1 year

Aucun formatage requis, le format codé en dur disparaît.

3 votes

0 votes

Oui et non, je pensais qu'il y avait une bonne solution JavaScript pour cela...

0 votes

Seconds est une forme lisible par l'homme.

81voto

Royi Namir Points 34397
 function secondsToString(seconds)
{
var numyears = Math.floor(seconds / 31536000);
var numdays = Math.floor((seconds % 31536000) / 86400); 
var numhours = Math.floor(((seconds % 31536000) % 86400) / 3600);
var numminutes = Math.floor((((seconds % 31536000) % 86400) % 3600) / 60);
var numseconds = (((seconds % 31536000) % 86400) % 3600) % 60;
return numyears + " years " +  numdays + " days " + numhours + " hours " + numminutes + " minutes " + numseconds + " seconds";

}

1 votes

Merci. Si vous ajoutez la vérification du pluriel (année/années), ce serait parfait !

0 votes

Merci pour votre aide, Royi. Voir ma réponse ci-dessous qui répond complètement à ma question

5 votes

Et les chiffres magiques : secondsInAYear = 31536000; secondsInADay = 86400; secondsInAnHour = 3600; secondsInAMinute = 60;

73voto

Dan Points 7078

Avec l'aide de Royi nous avons un code qui produit l'intervalle de temps sous une forme lisible par l'homme :

function millisecondsToStr (milliseconds) {
    // TIP: to find current time in milliseconds, use:
    // var  current_time_milliseconds = new Date().getTime();

    function numberEnding (number) {
        return (number > 1) ? 's' : '';
    }

    var temp = Math.floor(milliseconds / 1000);
    var years = Math.floor(temp / 31536000);
    if (years) {
        return years + ' year' + numberEnding(years);
    }
    //TODO: Months! Maybe weeks? 
    var days = Math.floor((temp %= 31536000) / 86400);
    if (days) {
        return days + ' day' + numberEnding(days);
    }
    var hours = Math.floor((temp %= 86400) / 3600);
    if (hours) {
        return hours + ' hour' + numberEnding(hours);
    }
    var minutes = Math.floor((temp %= 3600) / 60);
    if (minutes) {
        return minutes + ' minute' + numberEnding(minutes);
    }
    var seconds = temp % 60;
    if (seconds) {
        return seconds + ' second' + numberEnding(seconds);
    }
    return 'less than a second'; //'just now' //or other string you like;
}

3 votes

C'est faux. Pour un temps comme '3 jours 0 heure 50 minutes 36 secondes', il n'obtient que '3 jours', parce qu'il renvoie lorsque l'heure coïncide avec '0'.

61voto

urish Points 1969

Si vous êtes intéressé par une bibliothèque javascript existante qui fait très bien le travail, vous pouvez vérifier moment.js .

Plus précisément, le morceau de moment.js pertinent pour votre question est le suivant durées .

Voici quelques exemples de la manière dont vous pouvez en tirer parti pour accomplir votre tâche :

var duration = moment.duration(31536000);

// Using the built-in humanize function:
console.log(duration.humanize());   // Output: "9 hours"
console.log(duration.humanize(true));   // Output: "in 9 hours"

moment.js a une prise en charge intégrée de plus de 50 langues humaines, donc si vous utilisez l'option humanize() vous bénéficiez gratuitement d'une assistance multilingue.

Si vous souhaitez afficher l'information sur l'heure exacte, vous pouvez profiter de la fonction moment-précision-distance plug-in pour moment.js qui a été créé exactement dans ce but :

console.log(moment.preciseDiff(0, 39240754000);
// Output: 1 year 2 months 30 days 5 hours 12 minutes 34 seconds

Une chose à noter est qu'actuellement, moment.js ne prend pas en charge les semaines / jours (en semaine) pour l'objet durée.

J'espère que cela vous aidera !

31voto

Martin Points 845

J'ai pris un élan basé sur la réponse de @Royi :

/**
 * Translates seconds into human readable format of seconds, minutes, hours, days, and years
 * 
 * @param  {number} seconds The number of seconds to be processed
 * @return {string}         The phrase describing the amount of time
 */
function forHumans ( seconds ) {
    var levels = [
        [Math.floor(seconds / 31536000), 'years'],
        [Math.floor((seconds % 31536000) / 86400), 'days'],
        [Math.floor(((seconds % 31536000) % 86400) / 3600), 'hours'],
        [Math.floor((((seconds % 31536000) % 86400) % 3600) / 60), 'minutes'],
        [(((seconds % 31536000) % 86400) % 3600) % 60, 'seconds'],
    ];
    var returntext = '';

    for (var i = 0, max = levels.length; i < max; i++) {
        if ( levels[i][0] === 0 ) continue;
        returntext += ' ' + levels[i][0] + ' ' + (levels[i][0] === 1 ? levels[i][1].substr(0, levels[i][1].length-1): levels[i][1]);
    };
    return returntext.trim();
}

Ce qui est bien avec le mien, c'est qu'il n'y a pas de répétitions. if et ne vous donnera pas 0 année 0 jour 30 minutes 1 seconde par exemple.

Par exemple :

forHumans(60) sorties 1 minute

forHumans(3600) sorties 1 hour

y forHumans(13559879) sorties 156 days 22 hours 37 minutes 59 seconds

1 votes

Comment le rendre plus convivial pour les anglophones ? forHumans(13559879) -> 156 days, 22 hours, 37 minutes, and 59 seconds ? Cela devrait être la réponse acceptée.

0 votes

Lien brisé maintenant

16voto

reporter Points 2480

Essayez de suivre :

seconds = ~~(milliseconds / 1000);
minutes = ~~(seconds / 60);
hours = ~~(minutes / 60);
days = ~~(hours / 24);
weeks = ~~(days / 7);
year = ~~(days / 365);

Note :

  • Une année normale compte 365 jours. Une année bissextile compte 366 jours. Vous devez donc effectuer une vérification supplémentaire pour savoir si cela vous concerne.
  • Le même problème se pose avec l'heure d'été. Certains jours ont 23 et d'autres 25 heures au moment du changement d'heure.

Conclusion : il s'agit d'un extrait grossier mais petit et simple :)

0 votes

Réécriture de votre code un peu selon les tests de bemchmark montrant parseInt est trop lent

0 votes

Cela ne fonctionne pas. Par exemple, si millisecondes est 300000 (5 minutes), cela donne millisecondes=300000, secondes=300, minutes=5, ce qui n'est pas le résultat demandé par le PO. jsfiddle.net/yp6fcacs

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X