Converta o intervalo de tempo dado em segundos para uma forma mais legível por humanos

Eu preciso de um trecho de código para converter quantidade de tempo dado por número de segundos em algum formulário legível. A function deve receber um número e gerar uma string como esta:

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

Nenhuma formatação exigida, o formato codificado irá.

  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"; } 

Com a ajuda de Royi, temos um código que gera o intervalo de tempo em um formato legível :

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

Se você está interessado em uma biblioteca javascript existente que faz o trabalho muito bem, você pode querer verificar o moment.js .

Mais especificamente, a peça relevante do moment.js para sua pergunta é durações .

Aqui estão alguns exemplos de como você pode aproveitá-lo para alcançar sua tarefa:

 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" 

O moment.js tem suporte embutido para mais de 50 idiomas humanos, portanto, se você usar o método humanize humanize() , terá suporte a vários idiomas gratuitamente.

Se você deseja exibir as informações exatas de horário, aproveite o plug-in moment-precise-range para o moment.js que foi criado exatamente para essa finalidade:

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

Uma coisa a notar é que atualmente o moment.js não suporta semanas / dias (na semana) para o object duration.

Espero que isto ajude!

Tente seguir:

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

Nota:

  • Um ano normal tem 365 dias. Um ano bissexto tem 366 dias, então você precisa verificar se isso é um problema para você.
  • O problema semelhante com o horário de verão. Alguns dias têm 23 e 25 horas quando o tempo muda.

Conclusão: este é um trecho grosseiro, mas pequeno e simples 🙂

 millisToTime = function(ms){ x = ms / 1000; seconds = Math.round(x % 60); x /= 60; minutes = Math.round(x % 60); x /= 60; hours = Math.round(x % 24); x /= 24; days = Math.round(x); return {"Days" : days, "Hours" : hours, "Minutes" : minutes, "Seconds" : seconds}; } 

Isso levará milissegundos como int e fornecerá a você um object JSON contendo todas as informações necessárias

Muito mais simples e legível.

 milliseconds = 12345678; mydate=new Date(milliseconds); humandate=mydate.getUTCHours()+" hours, "+mydate.getUTCMinutes()+" minutes and "+mydate.getUTCSeconds()+" second(s)"; 

Que dá:

“3 horas, 25 minutos e 45 segundo (s)”

Tomou um balanço com base na resposta do @ 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 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(); } 

A coisa boa sobre o meu é que não há nenhum repetitivo if s, e não lhe dará 0 anos 0 dias 30 minutos 1 segundo por exemplo.

Por exemplo:

forHumans(60) saídas 1 minute

forHumans(3600) saídas 1 hour

e forHumans(13559879) saídas 156 days 22 hours 37 minutes 59 seconds

 function millisecondsToString(milliseconds) { var oneHour = 3600000; var oneMinute = 60000; var oneSecond = 1000; var seconds = 0; var minutes = 0; var hours = 0; var result; if (milliseconds >= oneHour) { hours = Math.floor(milliseconds / oneHour); } milliseconds = hours > 0 ? (milliseconds - hours * oneHour) : milliseconds; if (milliseconds >= oneMinute) { minutes = Math.floor(milliseconds / oneMinute); } milliseconds = minutes > 0 ? (milliseconds - minutes * oneMinute) : milliseconds; if (milliseconds >= oneSecond) { seconds = Math.floor(milliseconds / oneSecond); } milliseconds = seconds > 0 ? (milliseconds - seconds * oneSecond) : milliseconds; if (hours > 0) { result = (hours > 9 ? hours : "0" + hours) + ":"; } else { result = "00:"; } if (minutes > 0) { result += (minutes > 9 ? minutes : "0" + minutes) + ":"; } else { result += "00:"; } if (seconds > 0) { result += (seconds > 9 ? seconds : "0" + seconds) + ":"; } else { result += "00:"; } if (milliseconds > 0) { result += (milliseconds > 9 ? milliseconds : "0" + milliseconds); } else { result += "00"; } return result; } 

Para converter o tempo em milissegundos para o formato legível por humanos.

  function timeConversion(millisec) { var seconds = (millisec / 1000).toFixed(1); var minutes = (millisec / (1000 * 60)).toFixed(1); var hours = (millisec / (1000 * 60 * 60)).toFixed(1); var days = (millisec / (1000 * 60 * 60 * 24)).toFixed(1); if (seconds < 60) { return seconds + " Sec"; } else if (minutes < 60) { return minutes + " Min"; } else if (hours < 24) { return hours + " Hrs"; } else { return days + " Days" } } 

Esta function gera segundos neste formato: 11h 22m, 1y 244d, 42m 4s etc Configure a variável max para mostrar quantos identificadores você quiser.

 function secondsToString (seconds) { var years = Math.floor(seconds / 31536000); var max =2; var current = 0; var str = ""; if (years && current 

Para mostrar apenas o que você precisa e não o dia 0, horas 0 …

 formatTime = function(time) { var ret = time % 1000 + ' ms'; time = Math.floor(time / 1000); if (time !== 0) { ret = time % 60 + "s "+ret; time = Math.floor(time / 60); if (time !== 0) { ret = time % 60 + "min "+ret; time = Math.floor(time / 60); if (time !== 0) { ret = time % 60 + "h "+ret; ... } } } return ret; }; 

Com a ajuda de Dan resposta, eu vim com isso se você quiser calcular a diferença entre o tempo de pós-criado (do database deve ser recuperado como UTC) e o tempo do sistema de usuários e, em seguida, mostrar-lhes o tempo decorrido, você poderia usar abaixo da function

 function dateToStr(input_date) { input_date= input_date+" UTC"; // convert times in milliseconds var input_time_in_ms = new Date(input_date).getTime(); var current_time_in_ms = new Date().getTime(); var elapsed_time = current_time_in_ms - input_time_in_ms; function numberEnding (number) { return (number > 1) ? 's' : ''; } var temp = Math.floor(elapsed_time / 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; } 

por exemplo: uso

 var str = dateToStr('2014-10-05 15:22:16'); 

Esta é uma solução. Mais tarde, você pode dividir por “:” e obter os valores da matriz

  /** * 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(':'); } //Example var delay = 190980000; var fullTime = dhm(delay); console.log(fullTime); 

Sou um grande fã de objects, então criei isso em https://metacpan.org/pod/Time::Seconds

Uso:

 var human_readable = new TimeSeconds(986543).pretty(); // 11 days, 10 hours, 2 minutes, 23 seconds ;(function(w) { var interval = { second: 1, minute: 60, hour: 3600, day: 86400, week: 604800, month: 2629744, // year / 12 year: 31556930 // 365.24225 days }; var TimeSeconds = function(seconds) { this.val = seconds; }; TimeSeconds.prototype.seconds = function() { return parseInt(this.val); }; TimeSeconds.prototype.minutes = function() { return parseInt(this.val / interval.minute); }; TimeSeconds.prototype.hours = function() { return parseInt(this.val / interval.hour); }; TimeSeconds.prototype.days = function() { return parseInt(this.val / interval.day); }; TimeSeconds.prototype.weeks = function() { return parseInt(this.val / interval.week); }; TimeSeconds.prototype.months = function() { return parseInt(this.val / interval.month); }; TimeSeconds.prototype.years = function() { return parseInt(this.val / interval.year); }; TimeSeconds.prototype.pretty = function(chunks) { var val = this.val; var str = []; if(!chunks) chunks = ['day', 'hour', 'minute', 'second']; while(chunks.length) { var i = chunks.shift(); var x = parseInt(val / interval[i]); if(!x && chunks.length) continue; val -= interval[i] * x; str.push(x + ' ' + (x == 1 ? i : i + 's')); } return str.join(', ').replace(/^-/, 'minus '); }; w.TimeSeconds = TimeSeconds; })(window); 

Eu limpei uma das outras respostas um pouco fornece boas sequências de estilo ’10 segundos atrás’:

 function msago (ms) { function suffix (number) { return ((number > 1) ? 's' : '') + ' ago'; } var temp = ms / 1000; var years = Math.floor(temp / 31536000); if (years) return years + ' year' + suffix(years); var days = Math.floor((temp %= 31536000) / 86400); if (days) return days + ' day' + suffix(days); var hours = Math.floor((temp %= 86400) / 3600); if (hours) return hours + ' hour' + suffix(hours); var minutes = Math.floor((temp %= 3600) / 60); if (minutes) return minutes + ' minute' + suffix(minutes); var seconds = Math.floor(temp % 60); if (seconds) return seconds + ' second' + suffix(seconds); return 'less then a second ago'; }; 

Seguindo uma abordagem semelhante ao @Dan, modifiquei o código do @Royi Namir para gerar uma string com vírgulas e:

 secondsToString = function(seconds) { var numdays, numhours, nummilli, numminutes, numseconds, numyears, res; numyears = Math.floor(seconds / 31536000); numdays = Math.floor(seconds % 31536000 / 86400); numhours = Math.floor(seconds % 31536000 % 86400 / 3600); numminutes = Math.floor(seconds % 31536000 % 86400 % 3600 / 60); numseconds = seconds % 31536000 % 86400 % 3600 % 60; nummilli = seconds % 1.0; res = []; if (numyears > 0) { res.push(numyears + " years"); } if (numdays > 0) { res.push(numdays + " days"); } if (numhours > 0) { res.push(numhours + " hours"); } if (numminutes > 0) { res.push(numminutes + " minutes"); } if (numseconds > 0) { res.push(numminutes + " seconds"); } if (nummilli > 0) { res.push(nummilli + " milliseconds"); } return [res.slice(0, -1).join(", "), res.slice(-1)[0]].join(res.length > 1 ? " and " : ""); }; 

Não tem período então pode-se adicionar sentenças depois, como aqui:

 perform: function(msg, custom, conn) { var remTimeLoop; remTimeLoop = function(time) { if (time !== +custom[0]) { msg.reply((secondsToString(time)) + " remaining!"); } if (time > 15) { return setTimeout((function() { return remTimeLoop(time / 2); }), time / 2); } }; // ... remTimeLoop(+custom[0]); } 

Onde custom[0] é o tempo total de espera; Ele continuará dividindo o tempo por 2, avisando o tempo restante até que o timer termine e pare de avisar quando o tempo for inferior a 15 segundos.

 function secondsToTimeString(input) { let years = 0, days = 0, hours = 0, minutes = 0, seconds = 0; let ref = [31536000,86400,3600,60,1]; for (let i = 0;i < ref.length;i++) { let val = ref[i]; while (val <= input) { input -= val; if (i === 0) years++; if (i === 1) days++; if (i === 2) hours++; if (i === 3) minutes++; if (i === 4) seconds++; } 

return {anos, dias, horas, minutos, segundos}; }