Как я могу очеловечить эту полную продолжительность в moment.js / javascript

У меня есть счетчик оставшегося времени для загрузки файлов. Оставшаяся продолжительность рассчитывается и преобразуется в миллисекунды следующим образом:

var elapsedTime = e.timeStamp - timestarted;
var speed = e.loaded / elapsedTime;
var estimatedTotalTime = e.totalSize / speed;
var timeLeftInSeconds = (estimatedTotalTime - elapsedTime) / 1000;

Затем я строю массив, который я собираюсь встроить в гуманизированную строку. Массив выглядит следующим образом:

var time = {
              years : Math.round(moment.duration(timeLeftInSeconds, 'milliseconds').years()),
              months : Math.round(moment.duration(timeLeftInSeconds, 'milliseconds').months()),
              days : Math.round(moment.duration(timeLeftInSeconds, 'milliseconds').days()),
              hours : Math.round(moment.duration(timeLeftInSeconds, 'milliseconds').hours()),
              minutes : Math.round(moment.duration(timeLeftInSeconds, 'milliseconds').minutes()),
              seconds : Math.round(moment.duration(timeLeftInSeconds, 'milliseconds').seconds())
};

Это все работает отлично, и если я выведу строковое представление этих данных следующим образом:

  console.log(time.years + ' years, ' + time.months + ' months, ' + time.days + ' days, ' + time.hours + ' hours, '+ time.minutes + ' minutes, ' + time.seconds + ' seconds');

И это возвращает хороший простой поток оставшегося времени, например, так:

0 years, 0 months, 0 days, 0 hours, 1 minutes, 7 seconds

Что мне теперь нужно сделать, так это гуманизировать этот вывод, чтобы строка строилась в зависимости от оставшегося времени. например

  • 2 года и 3 месяца осталось
  • 1 час 32 минуты 41 секунда осталось
  • 7 секунд осталось
  • 3 минуты 46 секунд осталось
  • 6 секунд осталось

и т.д... и т.д...

Теперь я знаю, что moment.js имеет возможность автоматически гуманизировать длительности, что прекрасно работает для отдельных значений, но может иметь несколько возможных значений (часы / минуты / секунды и т. Д.)

Как я могу пойти о гуманизации этих данных либо с помощью moment.js, либо путем создания строки вручную?

Заранее спасибо.

3 ответа

Решение

Я думаю, что ваша лучшая ставка будет что-то вроде этого:

function humanize(time){
    if(time.years   > 0){   return time.years   + ' years and '     + time.months   + ' months remaining';}
    if(time.months  > 0){   return time.months  + ' months and '    + time.days     + ' days remaining';}
    if(time.days    > 0){   return time.days    + ' days and '      + time.hours    + ' hours remaining';}
    if(time.hours   > 0){   return time.hours   + ' hours and '     + time.minutes  + ' minutes and ' + time.seconds + ' seconds remaining';}
    if(time.minutes > 0){   return time.minutes + ' minutes and '   + time.seconds  + ' seconds remaining';}
    if(time.seconds > 0){   return time.seconds + ' seconds remaining';}
    return "Time's up!";
}

В качестве альтернативы вы можете использовать эту функцию:

function humanize(time){
    var o = '';
    for(key in time){
        if(time[key] > 0){
            if(o === ''){
                o += time[key] + ' ' + key + ' ';
            }else{
                return o + 'and ' + time[key] + ' ' + key + ' remaining';
            }
        }
    }
    return o + 'remaining';
}

Возвращается "x <time> and y <time> remaining", для 2 самых больших значений. (Или только секунды в последнем случае.

Моя библиотека HumanizeDuration.js звучит именно так, как вы хотите:

humanizeDuration(1);         // "1 millisecond"
humanizeDuration(3000);      // "3 seconds"
humanizeDuration(2012);      // "2 seconds, 12 milliseconds"
humanizeDuration(97320000);  // "1 day, 3 hours, 2 minutes"

Похоже, мой ответ немного запоздал, но, может быть, это поможет другим взглянуть на этот вопрос!

Вы должны попробовать этот плагин: момент-продолжительность-формат

Его синтаксис очень удобен:

var moment = require('moment');
require("moment-duration-format");
moment.duration(32832, "seconds").format("h [hrs]: m [min]: s [sec]")
// => 9 hrs: 7 min: 12 sec" 

В итоге я остался доволен форматом date-fns formatDistanceToNow. Вы можете добавить эту функцию, не добавляя всю библиотеку, например moment.js

Другие вопросы по тегам